Python 面向对象
鸭子
架构
如果 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是实现基础 有需要再看