实例与类动态添加方法
实例添加属性:
def Student(object):
pass
s = Student()
s.name = ‘syz’
实例添加方法
from types import MethodType
def set_name(self,name):
self.name = name
s.set_name = MethodType(set_name,s)
类添加方法
Student.set_name = set_name
__slots__
限定动态添加类的属性,通过tuple的方式
__slots__=(‘name’,’score’)
限定动态添加的属性只能是name 跟score
类似的__x__的方法属于特殊方法,例如__init__方法、自带str类的__len__()方法,让该方法作用于class,len(‘123’),而普通的len()方法则需要通过x.len()使用
@property
由于检查参数需要添加get或者set函数,而为了提高访问的效率,可以通过修饰器的方式修改get或者set函数的方式,类可以通过student.a或者student.a=a的方式直接调用类的函数。
calss Student(object):
@property
def birth(self):
return self._birth
@birth.setter(self,value):
if birth > 100:
self._birth = value
else:
raise ValueError(‘birth must be in 200!’) #读写 @property
def age(self):
return self._age #只读
多重继承
多重继承的父类后面加上MaxIn用以区分
calss dag(Animal,CanrunMaxIn,EatFeatMaxIn):
pass
__str__ __call__ callable() __getattr__
__str__直接打印函数是可以查看重要的参数
calss Student(object):
def __str__(self):
print(‘重要参数!’)
__repr__ = __str__
print(Student())
s = Student()
print(s)
__call__考虑把类当成函数调用时
Student()
class Student(object):
def __init__(self, name):
self.name = name def __call__(self):
print('My name is %s.' % self.name)
调用方式如下:
>>> s = Student('Michael')
>>> s() # self参数不要传入
My name is Michael.
那么,怎么判断一个变量是对象还是函数呢?其实,更多的时候,我们需要判断一个对象是否能被调用,能被调用的对象就是一个Callable对象,比如函数和我们上面定义的带有__call__()的类实例:
>>> callable(Student())
True
>>> callable(max)
True
>>> callable([1, 2, 3])
False
>>> callable(None)
False
>>> callable('str')
False
__getattr__ 当调用的属性为动态的时,进行设置
class Student(object): def __getattr__(self, attr):
if attr=='age':
return lambda: 25
raise AttributeError('\'Student\' object has no attribute \'%s\'' % attr)
这实际上可以把一个类的所有属性和方法调用全部动态化处理了,不需要任何特殊手段。
这种完全动态调用的特性有什么实际作用呢?作用就是,可以针对完全动态的情况作调用
枚举类
把固定不变的数以枚举类的实例形式实现
例如日期、月份等
from enum import Enum
Mouth = Enum(‘Month’,(‘Jan’’Feb’))
from enum import Enum
Month = Enum('Month', ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'))
from enum import Enum, unique @unique
class Weekday(Enum):
Sun = 0 # Sun的value被设定为0
Mon = 1
Tue = 2
Wed = 3
Thu = 4
Fri = 5
Sat = 6
value属性则是自动赋给成员的int常量,默认从1开始计数。
如果需要更精确地控制枚举类型,可以从Enum派生出自定义类:
from enum import Enum, unique @unique
class Weekday(Enum):
Sun = 0 # Sun的value被设定为0
Mon = 1
Tue = 2
Wed = 3
Thu = 4
Fri = 5
Sat = 6
@unique装饰器可以帮助我们检查保证没有重复值。
访问这些枚举类型可以有若干种方法:
>>> day1 = Weekday.Mon
>>> print(day1)
Weekday.Mon
>>> print(Weekday.Tue)
Weekday.Tue
>>> print(Weekday['Tue'])
Weekday.Tue
>>> print(Weekday.Tue.value)
2
>>> print(day1 == Weekday.Mon)
True
>>> print(day1 == Weekday.Tue)
False
>>> print(Weekday(1))
Weekday.Mon
>>> print(day1 == Weekday(1))
True
>>> Weekday(7)
Traceback (most recent call last):
...
ValueError: 7 is not a valid Weekday
>>> for name, member in Weekday.__members__.items():
... print(name, '=>', member)
...
Sun => Weekday.Sun
Mon => Weekday.Mon
Tue => Weekday.Tue
Wed => Weekday.Wed
Thu => Weekday.Thu
Fri => Weekday.Fri
Sat => Weekday.Sat