文章目录
为实例和类绑定属性和方法
- 创建类
class Animal(object):
pass
- 绑定实例
>>> dog = Animal() # 创建实例
>>> dog.name = 'Dura' # 为实例添加属性
>>> def set_age(self,age): # 为实例添加方法
self.age = age
>>> from type import MethodType
>>> dog.set_age = MethodType(set_age,dog)
>>> dog.set_age(2) # dog.age 2
>>> cat = Animail()
>>> cat.age # 实例添加的属性或方法,其他实例不可调用
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Animal' object has no attribute 'set_age'
>>> Animal.set_age = set_age # 为类添加方法,实例均可调用
__slots__限制当前class实例,对子类不管用
class Animal(object):
__solts__ = (name,age) # 实例不能访问或修改除了name/age以外的属性
class Dog(Animal):
pass # 子类Dog的实例可以创建自己的属性
@property装饰器,将getter
方法变成属性
class Animal(object):
@propety # 将gettar方法变成属性,创建了一个@birth.settar的装饰器
def birth(self):
return self._birth
@birth.setter # @birth.settar装饰器将setter方法变成属性赋值
def birth(self,value):
if not isinstance(value, int):
raise ValueError('Bad Vaule Type')
self._birth = value
@propety # 只定义getter方法,不定义setter方法时,则该属性为只读属性
def age(self):
return 2019 - self._birth
多重继承 —— 一个子类可同时获得多个父类的所有功能[Mixin
]
class AMixin(object): # Mixin : 给一个类增加多个功能
def foo(self):
print('A foo')
def bar(self):
print('A bar')
class BMixin(object):
def foo(self):
print('B foo')
def bar(self):
print('B bar')
class C1Mixin(AMixin,BMixin): # 继承顺序:入度为0 -- 最左原则
pass
class C2Mixin(AMixin,BMixin):
def bar(self):
print('C2-bar')
class D(C1Mixin,C2Mixin):
pass
if __name__ == '__main__':
print(D.__mro__)
d=D()
d.foo()
d.bar()
继承关系图为
输出结果为
(<class '__main__.D'>, <class '__main__.C1'>, <class '__main__.C2'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
A foo
C2-bar
定制类
形如__xxx__的变量或函数名
__str__()
:打印实例更好看
class Animal(object):
def __init__(self,name):
self.name = name
def __str__(self):
return 'Animal Object (name: %s)' % self.name
声明实例调用时,可调用__str__(),隐藏实例内部信息
>>> ani = Animal('Jessica')
>>> ani # 直接显示变量调用的是__repr__()函数,而不是__str__()
<__main__.Student object at 0x109afb310>
>>> print(ani) # 打印是给客户看的;直接显示是给程序开发者看的,用于调试
'Animal Object (name: Jessica)'
__iter__()
:用于类中存在for … in …的情况,返回一个迭代对象
class Fib(object):
def __init__(self): # 初始化计算器a,b
self.a, self.b = 0, 1
def __iter__(self): # 实例本身就是迭代对象,返回自己
return self
def __next__(self): # 获取循环的下一个值,直到循环结束
self.a, self.b = self.b, self.a + self.b
if(self.a > 10): # 循环截止条件
raise Stopiteration()
return self.a
获取结果
>>> for i in Fib()
print(i)
1
1
2
3
5
8
__getitem__()
:根据下标获取元素
class Fib(object):
def __getitem__(self,n):
a, b = 1, 1
for x in range(n):
a, b = b, a + b
return a
获取结果
>>> f = Fib()
>>>f[3]
3
__getattr__()
:未找到属性的情况下,调用
class Chain(object):
def __init__(self, path=''):
self._path = path
def __getattr__(self, path): # 没有找到路径时,调用
return Chain('%s/%s' % (self._path, path))
def __str__(self): # 修改打印信息,隐藏类的关键信息
return self._path
__repr__ = __str__ # 直接显示与打印内容相同
获取结果
>>> Chain().status.user.timeline.list
/status/user/timeline/list
__call__()
:直接对实例进行调用
class Animal(object):
def __init__(self, name):
self.name = name
def __call__(self):
print('Hello, %s' % self.name)
获取结果
>>> ani = Animal('Beer')
>>> ani()
'Hello, Beer'
通过callable()函数,可判断一个对象是否为“可调用”对象
>>> callable(Animal())
True
>>> callable([1,2,3])
False
枚举类
定义一个Month的枚举类,可以直接引用一个常量或枚举出所有成员
from enum import Enum
Month = Enum('Month', ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun','Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'))
for name,member in Month.__members__.items(): # 枚举所有成员
print(name, '=>', member, ',', member.value);
输出为:
Jan => Month.Jan , 1
Feb => Month.Feb , 2
Mar => Month.Mar , 3
Apr => Month.Apr , 4
May => Month.May , 5
Jun => Month.Jun , 6
Jul => Month.Jul , 7
Aug => Month.Aug , 8
Sep => Month.Sep , 9
Oct => Month.Oct , 10
Nov => Month.Nov , 11
Dec => Month.Dec , 12
更精确地控制枚举类型
from enum import Enum
@unique # 检查保证无重复值
class Weekday(Enum):
Sun = 0 # name为Sun,iterm为Weekday.Sun的value为0
Mon = 1
Tue = 2
Wed = 3
Thu = 4
Fri = 5
Sat = 6
print(Weekdy.Sun)
print(Weekdy.Sun.value)
for name,member in Weekday.__members__.items():
print(name, '=>', member)
输出为:
Weekdy.Sun
0
Sun => Weekday.Sun
Mon => Weekday.Mon
Tue => Weekday.Tue
Wed => Weekday.Wed
Thu => Weekday.Thu
Fri => Weekday.Fri
Sat => Weekday.Sat
元类
type()函数构建class方法:
def f(self, name = 'world'): # 定义函数
print('Hello, %s' % name)
Hello = type('Hello', (object,), dict(hello = f)) # type()定义class,三个参数(class名称,继承的父类集合,定义class内置方法)
h = Hello() # 初始化实例h
print(h.hello()) # ‘Hello, World'
print(type(Hello)) # <class 'Type'> class的类型为‘type’
print(type(h)) # <class '__main__'.Hello> 实例的类型为class