从零开始学Python-Day43-面向对象高级编程-使用__slots__

Python零基础 木人张 3年前 (2020-04-16) 872次浏览 0个评论 扫描二维码
文章目录[隐藏]

当我们定义了类class并创建它的实例之后,我们可以给这个实例绑定任何属性和方法,这就是动态语言的灵活性。

我们定义一个class:

>>> class Student(object):
	pass

给创建的实例绑定属性:

>>> s = Student()
>>> s.name = 'Woodman'
>>> print(s.name)
Woodman

也可以给实例绑定方法:

>>> def set_age(self, age):
	self.age = age

>>> from types import MethodType
>>> s.set_age = MethodType(set_age, s)
>>> s.set_age(35)
>>> s.age
35

需要注意的是,给一个实例绑定的属性和方法对同一个类的其他实例是不起作用的,这个其实也很好理解,如果要给所有实例都绑定属性或方法就需要对class类去绑定。

>>> s2 = Student()
>>> s2.set_age(33)
Traceback (most recent call last):
  File "<pyshell#14>", line 1, in <module>
    s2.set_age(33)
AttributeError: 'Student' object has no attribute 'set_age'

给class绑定属性和方法后,其他实例均可调用:

>>> def set_score(self, score):
	self.score = score

>>> Student.set_score = set_score
>>> s.set_score(100)
>>> s.score
100
>>> s2.set_score(60)
>>> s2.score
60

上面的set_score方法可以直接定义在class中,但动态绑定允许我们在程序运行的过程中动态给class加上功能,这在静态语言中很难实现。

__slots__

但是,如果我们想要限制实例的属性怎么办?比如,只允许对Student实例添加name和age属性。为了达到限制的目的,Python允许在定义class的时候,定义一个特殊的__slots__变量,来限制该class实例能添加的属性:

>>> class Student(object):
	__slots__ = ('name','age')

	
>>> s = Student()
>>> s.name = 'Woodman'
>>> s.age = 35
>>> s.score = 100
Traceback (most recent call last):
  File "<pyshell#29>", line 1, in <module>
    s.score = 100
AttributeError: 'Student' object has no attribute 'score'

可以看到,由于做了slots限制,score这一属性添加不上去,使用__slots__要注意,__slots__定义的属性仅对当前类实例起作用,对继承的子类不起作用:

>>> class GraduatStudent(Student):
	pass

>>> g = GraduatStudent()
>>> g.score = 100

除非在子类中也定义__slots__,这样,子类实例允许定义的属性就是自身的__slots__加上父类的__slots__。


木人张,版权所有丨如未注明 , 均为原创,禁止转载。
喜欢 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址