python __slot__和@property问题

现在定义一个Student1类,用__slot__限定这个类可以添加的属性,然后程序运行的时候,立马报错:

clipboard.png

class Student1(object):
    __slots__ = ('name','age','score','birth')
    
    def __init__(self,name,age):
        self.name = name
        self.age = age

    @property
    def birth(self):
        return self.birth

    @birth.setter
    def birth(self,value):
        self.birth = value

    @property
    def score(self):
        return self.score

    @score.setter
    def score(self,value):
        self.score = value

想请教下各位大神,为什么会报错说score和birth与类里面的变量冲突呢,难道是score和birth与类中装饰器修饰的函数birth和score重名了?
谢谢各位


我尝试把__slots__里面的内容改了一下,把birth和score分别改成s_birth,s_score,下面的@property和setter方法里面对应位置也改了,就不报错了:

class Student1(object):
    __slots__ = ('name','age','s_score','s_birth')
    
    def __init__(self,name,age):
        self.name = name
        self.age = age


    @property
    def birth(self):
        return self.s_birth

    @birth.setter
    def birth(self,value):
        self.s_birth = value

    @property
    def score(self):
        return self.s_score

    @score.setter
    def score(self,value):
        self.s_score = value
阅读 1.9k
1 个回答

这个我测试过,认为与property无关,这应该跟class 的 __dict__能拉上点关系。
以下面为例:

class klass:

__slots__ = ('a','b')

def __init__(self):
    pass
def b(self):
    pass

一样会出现同样问题

把上面b 方法改成c 方法,我调用klass.__dict__ 列印出
省略。。。。。
'__slots__' :('a', 'b'),
省略。。。。。
'a' :xxxxxx,
'b' :xxxxxx,
'c' :'function xxxxxxx'

可见slots里面的属性除了作为slots自身的value(值)之外,还出现在__dict__里面各自作为key(键)。
那么可以想象,以上面原本klass为例,klass.__dict__ 已经有b这个key, 再加上slots里面的b也算上就两个b,冲突了。

当然,function的名字不在slots里面也可以实例化并且可以调用。

但据我所知,使用slots其中一个原因是为了节省内存,详情可以自行搜寻资料。

最后来自https://docs.python.org/zh-cn...
实在是看不懂,不知有关否?

slots 是通过为每个变量名创建描述器 (实现描述器) 在类层级上实现的。因此,类属性不能被用来为通过 slots 定义的实例变量设置默认值;否则,类属性就会覆盖描述器赋值。
slots are implemented at the class level by creating descriptors (Implementing Descriptors) for each variable name. As a result, class attributes cannot be used to set default values for instance variables defined by __slots__; otherwise, the class attribute would overwrite the descriptor assignment.

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题