Discuss / Python / 使用__slots__限制了实例属性,不限制类属性添加

使用__slots__限制了实例属性,不限制类属性添加

Topic source

测试了一下,使用slots限制了实例属性,不限制类属性添加

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

>>> s=Student()
>>> dir(s)
['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__slots__', '__str__', '__subclasshook__', 'age', 'name']
>>> s.name='zhangrr'
>>> s.age='21'
>>> s.score=100
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Student' object has no attribute 'score'

>>> setattr(s,'score',100)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Student' object has no attribute 'score'


>>> setattr(Student,'score',100)
>>> dir(Student)
['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__slots__', '__str__', '__subclasshook__', 'age', 'name', 'score']
>>> 
>>> Student.city='Shanghai'
>>> dir(Student)
['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__slots__', '__str__', '__subclasshook__', 'age', 'city', 'name', 'score']
class Student(object):
    __slots__ = ('name', 'age') 

Student.score=200
print(Student.score)
s=Student()
s.score=100

我也发现了,并且在向类Student添加了属性score后,再向实例s添加属性score报错为

AttributeError:'Student' object attribute 'score' is read-only

而不是

AttributeError:'Student' object has no attribute 'score'

class Student(object): pass a=Student() b=Student()

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

from types import MethodType Student.set_age=MethodType(set_age,Student)

a.set_age(11) print(a.age,b.age) b.set_age(15) print(a.age,b.age)

实例a应用了method set_age,实例b也继承了age的属性值;而b应用了set_age之后,age的值被覆盖了。 因此,通过方法添加的属性,实际上是类的属性,而且该属性值在类和实例中保持一致性--可将method中的self_age属性看成一个指针,类和实例共用该指针,指向同一个数值;而普通的属性,类和实例有各自的指针,实例和类可以指向不同的数值。 自己的理解,请指正。


  • 1

Reply