面向对象高级编程
参考链接:廖雪峰的官方网站
使用 __slots__
给实例绑定方法
在前面我们已经知道可以给类的实例绑定任何变量,而实际上作为动态语言的特点,不仅可以绑定变量,还可以给实例绑定方法,具体做法为:
>>> class Student(object):
... pass
...
>>> s = Student()
>>> def set_age(self, age):
... self.age = age
...
>>> from types import MethodType
>>> s.set_age = MethodType(set_age, s)
>>> s.set_age(25)
>>> s.age
25
当然只有绑定了这个方法的实例才能调用它,如果想要类的所有实例都能调用这个方法,可以给类绑定这个方法,具体做法为:
>>> def set_score(self, score):
... self.score = score
...
>>> Student.set_score = set_score
虽然说直接把set_score()
定义在类中也可以让所有实例能调用它,但动态绑定允许我们在程序运行中给类添加功能。
使用__slots__
使用__slots__
可以限制绑定给实例的属性,即让实例只能够绑定某些属性,用法如下:
class Student(object):
__slots__ = ('name', 'age') # 用tuple定义允许绑定的属性名称
这样Student
类的实例就只能绑定name
和age
属性了,如果试图绑定其他属性,就会报错:
>>> s.score = 99 # 绑定属性'score'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Student' object has no attribute 'score'
需要注意的__slots__
对类属性的限制仅对当前类实例起作用,不会影响到子类实例:
>>> class GraduateStudent(Student):
... pass
...
>>> g = GraduateStudent()
>>> g.score = 9999
使用@property
在之前的操作中我们可以对类实例的属性进行任意的更改,这可能会造成一些问题:
- 所有知道属性名的开发人员都可以修改属性值,尽管他们可能是无意的,但后果却十分严重
- 对属性值的修改没有范围限制,这样属性值可能不符合逻辑
如果我们想要限制对属性的修改的话,可以通过自定义一个set()
函数来实现,但这样代码就不简洁了,我们希望能够在直接给属性赋值的情况下依然可以限制范围,那么@property
就可以帮我们实现这种功能。
下面我以Rectangle
这个类为例来说明@property
的作用:
class Rectangle(object):
def __init__(self):
self.width =10
self.height=20
让width和height这两个属性不能被修改:
class Rectangle(object):
@property
def width(self):
return self._width
@property
def height(self):
return self._height
s = Rectangle()
#与方法名一致
s.width = 1024
s.height = 768
print(s.width,s.height)