Python面向对象高级编程
1.__slots__
通过Types包中的MethodType将外部方法与类对象进行绑定(该方法只能对绑定的对象生效)
"""a test module""" from types import MethodType __author__ = 'Jack Ma' class Student(object): """a test class""" pass def set_name(self, name): self.name = name; a = Student() a.set_name = MethodType(set_name, a, Student) a.set_name("Jack") print a.name
通过Types包中的MethodType将外部方法与类进行绑定(该方法能够被该类的所有对象使用)
"""a test module""" from types import MethodType __author__ = 'Jack Ma' class Student(object): """a test class""" pass def set_name(self, name): self.name = name; a = Student() b = Student() Student.set_name = MethodType(set_name, None, Student) a.set_name("Jack") b.set_name("Tom") print a.name print b.name
而当我们想对一个类可以赋予的属性进行限制,用到类的__slots__参数即可,__slots__赋值使用字符串为成员的元组进行赋值
class Student(object): """a test class""" __slots__ = ('name', 'age') pass def set_name(self, name): self.name = name; a = Student() Student.set_name = MethodType(set_name, None, Student) a.set_name("Jack") a.sex = "Male" print a.name, a.sex
结果是sex属性插入不了,报错
Traceback (most recent call last): File "F:/PyProject/test2.py", line 23, in <module> a.sex = "Male" AttributeError: 'Student' object has no attribute 'sex'
但是方法可以插入到类中
注意:使用__slots__
要注意,__slots__
定义的属性仅对当前类起作用,对继承的子类是不起作用的。除非在子类中也定义__slots__
,这样,子类允许定义的属性就是自身的__slots__
加上父类的__slots__
。
from types import MethodType __author__ = 'Jack Ma' class Student(object): """a test class""" __slots__ = ('name', 'age') pass class Class1(Student): """a test son Class""" __slots__ = () def set_name(self, name): self.name = name; a = Class1() Class1.set_name = MethodType(set_name, None, Class1) a.set_name("Jack") a.sex = "Male" print a.name, a.sex
此时,父类的__slots__限制才能生效
2.使用@property
class Student(object): """a test class""" @property def score(self): return self._score @score.setter def score(self, value): if not isinstance(value, int): raise ValueError('score must be an integer!') if value < 0 or value > 100: raise ValueError('score must between 0 ~ 100!') self._score = value a = Student() a.score = 11 print a.score
可以通过装饰器的setter属性 对score的设置属性进行限制
3.多继承
需要多继承时,在第二个类及之后的类后加上MiXin实现
class MyTCPServer(TCPServer, CoroutineMixin): pass
4.元类
用type()函数创建类
3个参数:
1.创建的类名 -- 字符串
2.父类 -- 元组
3.绑定的内容 -- 字典
def func(self, name): print "Hello %s !" % name Hello = type("Hello", (object,), {'hello': func}) a = Hello() a.hello("World")
Hello World !
除了使用type()
动态创建类以外,要控制类的创建行为,还可以使用metaclass。
metaclass,直译为元类,简单的解释就是:
当我们定义了类以后,就可以根据这个类创建出实例,所以:先定义类,然后创建实例。
但是如果我们想创建出类呢?那就必须根据metaclass创建出类,所以:先定义metaclass,然后创建类。
连接起来就是:先定义metaclass,就可以创建类,最后创建实例。
所以,metaclass允许你创建类或者修改类。换句话说,你可以把类看成是metaclass创建出来的“实例”。