Under normal circumstances, when we define a class and create an instance of a class, we can bind any attributes and methods to the instance, which is the flexibility of dynamic languages. First define the class:
class Student(object):
pass
Then, try to bind a property to the instance:
>>> s = Student()
>>> s.name = 'Michael' # 动态给实例绑定一个属性
>>> print(s.name) Michael
You can also try to bind a method to the instance:
>>> 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
However, a method bound to one instance has no effect on another:
To bind methods to all instances, bind methods to classes:
>>> def set_score(self, score): ... self.score = score ... >>> Student.set_score = set_score
After binding a method to a class, all instances can call:
>>> s.set_score(100)
>>> s.score
100
>>> s2.set_score(99) >>> s2.score 99
use __slots__
But what if we want to restrict the properties of the instance? For example, only adding name
and age
properties to the Student instance is allowed.
For the purpose of restriction, Python allows a special variable to be defined when defining a __slots__
class to limit the attributes that can be added to the class instance:
class Student(object):
__slots__ = ('name', 'age') # 用tuple定义允许绑定的属性名称
Then, let's try:
>>> s = Student() # 创建新的实例
>>> s.name = 'Michael' # 绑定属性'name' >>> s.age = 25 # 绑定属性'age' >>> s.score = 99 # 绑定属性'score' Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'Student' object has no attribute 'score'
The property cannot be bound because it is not put in , 'score'
trying to bind will get the error.__slots__
score
score
AttributeError
It should be __slots__
noted that the __slots__
defined properties only work on the current class instance, and have no effect on inherited subclasses:
>>> class GraduateStudent(Student): ... pass ... >>> g = GraduateStudent() >>> g.score = 9999
Unless it is also defined in the subclass, in __slots__
this way, the attributes allowed to be defined by the subclass instance are its own __slots__
plus the superclass __slots__
.