参考:
NOTE
1.动态语言灵活绑定属性及方法。
#!/usr/bin/env python3class MyClass(object): def __init__(self): passdef func(obj): print(obj.name, obj.age)def main(): h = MyClass() h.name = 'Chen' h.age = '20' func(h)if __name__ == '__main__': main()
给对象h绑定了属性name和age。
sh-3.2# ./oop7.py Chen 20
绑定一个新的方法:
from types import MethodTypedef f(self): print('I\'m new here!')h.f = MethodType(f, h) # new methodh.f()
I'm new here!
但是这种绑定的方法并不存在于新建的对象:
h1 = MyClass() h1.f()
Traceback (most recent call last): File "./oop7.py", line 28, inmain() File "./oop7.py", line 25, in main h1.f()AttributeError: 'MyClass' object has no attribute 'f'
给类绑定一个方法,解决这个问题:
MyClass.f = f h1 = MyClass() h1.f()
I'm new here!
通常情况下,上面的f方法可以直接定义在class中,但动态绑定允许我们在程序运行的过程中动态给class加上功能,这在静态语言中很难实现。
2.__slots__
但是,如果我们想要限制实例的属性怎么办?比如,只允许对MyClass实例添加name和age属性。
为了达到限制的目的,Python允许在定义class的时候,定义一个特殊的__slots__
变量,来限制该class实例能添加的属性:
#!/usr/bin/env python3class MyClass(object): """docstring for MyClass""" __slots__ = ('name', 'age') def __init__(self): super(MyClass, self).__init__() passdef main(): h = MyClass() h.name = 'Chen' h.age = 20 h.city = 'FuZhou'if __name__ == '__main__': main()
sh-3.2# ./oop8.py Traceback (most recent call last): File "./oop8.py", line 17, inmain() File "./oop8.py", line 14, in main h.city = 'FuZhou'AttributeError: 'MyClass' object has no attribute 'city'
__slots__
用tuple定义允许绑定的属性名称,由于'city'没有被放到__slots__中,所以不能绑定city属性。
使用__slots__
要注意,__slots__
定义的属性仅对当前类实例起作用,对继承的子类是不起作用的:
#!/usr/bin/env python3class MyClass(object): """docstring for MyClass""" __slots__ = ('name', 'age') def __init__(self): super(MyClass, self).__init__() passclass Student(MyClass): """docstring for Student""" def __init__(self): super(Student, self).__init__() pass def main(): h = MyClass() h.name = 'Chen' h.age = 20 # h.city = 'FuZhou' h1 = Student() h1.name = 'Chen' h1.age = 20 h1.city = 'FuZhou' print(h1.name, h1.age, h1.city)if __name__ == '__main__': main()
sh-3.2# ./oop8.py Chen 20 FuZhou
2017/3/2