鸭子架构

如果 c++叫紧致,这叫松散,类的属性/成员方法都可以随时绑定上去。

class Student(object):
    def __init__(self,name,score):
        self.name = name
        self.score = score

yang=Student('yang',99)
li =  Student('li',88)

def good_student(score):
    if score >= 90:
        print('good student')

#可以给实例随意增加成员..
yang.print_good = good_student
yang.print_good(99)


#property用法
class Screen(object):
    def __init__(self,name):
        self.name = name
    @property
    def width(self):
        return self._width
    @width.setter
    def width(self,w):
        if not isinstance(w,int):
            raise ValueError('width must be int')
        if w > 100 or w < 0:
            raise ValueError('must in r(0,100)')
        self._width = w

    @property
    def height(self):
        return self._width
    @height.setter
    def height(self,h):
        if not isinstance(h,int):
            raise ValueError('height must be int')
        if h > 100 or h < 0:
            raise ValueError('must in r(0,100)')
        self._height= h

    @property
    def age(self):
        return 10


sc = Screen('board')
sc.width= 50
print('width',sc.width)
#只读属性
print('age:',sc.age)

#多态
class Base(object):
    def show(self):
        print("base show")

class Son(Base):
    def show(self):
        print("son show")

def base_show(Base):
    Base.show()
base_show(Base())

base_show(Son())


#setattr可以随意添加新的属性
class Timer(object):
    def show(self):
        print('Start...')

base_show(Timer())

type(Base)

print(hasattr(Son(),'show'))

def show_again():
    print('new show')

f= show_again

#setattr with a func
a=Son()
setattr(a,'show_again',f)
print(hasattr(a,'show_again'))
a.show_again()

#给某个实例用MethodType绑定方法
#给一个实例绑定的方法,对另一个实例是不起作用
def son_name(self,name):
    self.name = name

def get_son_name(self):
    return self.name

from types import MethodType

s = Son()

s.son_name = MethodType(son_name,s)
s.get_son_name = MethodType(get_son_name,s)

s.son_name('bbb')
print(s.get_son_name())

##绑定到类上,则对所有实例起作用
Son.son_name = son_name
Son.get_son_name = get_son_name

s.son_name('ccc')
print(s.get_son_name())

#__slots__ = ('name', 'age') # 用tuple定义允许实例绑定的属性名称
class Dog(object):
    __slots__ = ('name','age')

d = Dog()
d.age = 10
d.name = 20
# d.sex = 'male
#AttributeError: 'Dog' object has no attribute 'sex'

#但是直接对类的绑定是允许的
Dog.sex = 'male'

print(d.sex)

print(Dog())


#内部属性调用的函数
#__str__()
#__len__()
#__getattr__()
#上面的getattr就是调用的__getarr__()
#在没有找到属性的情况下,才调用__getattr__

#链式调用
class Chain(object):

    def __init__(self, path=''):
        self._path = path
    def show(self):
        print(self._path)

    #新定义的attr返回一个Chain(),然后又调用了构造Chain('xx')
    #所以Chain('root/install').a.b.c 返回一个新的Chain
    def __getattr__(self, path):
        return Chain('%s/%s' % (self._path, path))

    # def __str__(self):
    #     return self._path
    # __repr__ = __str__

print(Chain('root/install').a.b.c)

a = Chain('root/install').a.b.c

a.show()

#__call__()实现了后,可以像使用函数一样使用对象,函数和对象在python里都是对象,其实没啥区别
#能否被调用用`callable`方法检查

class IamObj(object):
    def __call__(self,a,b):
        print('in call','a=',a,'b=',b)

i_am_obj = IamObj()

i_am_obj(1,2)

#枚举类
#unique装饰器可检查有无重复值
from enum import Enum, unique

Week=Enum('Week',('Mon','Tue','Wen','Thr','Fri','Sat','Sun'))

print(Week.Mon)

@unique
class Index(Enum):
    Aoa=1
    Adb=2
    Ios=3
    Axx='444'

#如果是整形值,value一下
print('aoa val:',Index.Aoa.value)
print('axx:',Index.Axx)

#type()函数可以查看一个类型或变量的类型
print(type(Index))

#type()函数既可以返回一个对象的类型,又可以创建出新的类型
#动态创建类,分分钟
#Python解释器遇到class定义时,仅仅是扫描一下class定义的语法,然后调用type()函数创建出class
def h(self,name):
    print('hello',name)

#动态 创建Hello类!  1名称 2父类 3 h绑定到hello上
Hello=type('Hello',(object,),dict(hello=h))

Json = Hello()

Json.hello('Json')

#类的类型就是`type`
print(type(Hello))
#__main__下创建的Hello的实例
print(type(Json))

#metaclass创建类,类看成是metaclass创建出来的“实例”
#ORM是实现基础 有需要再看