Python 子类安全类变量

Python 子类安全类变量,python,Python,我可以做到: class T(object): i = 5 # then use the value somewhere in a function def p(self): print id(i), T.i 。。但是,如果我碰巧遇到子类T class N(T): pass 。。那么N.i实际上就是T.i。我找到了解决这个问题的方法: class T(object): i = 5 def p(self): pr

我可以做到:

class T(object):
    i = 5

    # then use the value somewhere in a function
    def p(self):
        print id(i), T.i
。。但是,如果我碰巧遇到子类
T

class N(T):
    pass
。。那么
N.i
实际上就是
T.i
。我找到了解决这个问题的方法:

class T(object):
    i = 5
    def p(self):
        print self.__class__.i

。。这是正确的并且肯定有效吗?或者在某些情况下它会产生意想不到的行为(我不知道)?

嗯。。。您知道可以从实例引用类属性吗

class T(object):
    i = 5

    def p(self):
        print(id(self.i), self.i)

撇开课堂方法不谈,我想到了一个有趣的想法。为什么不使用访问基础类实例的属性呢

class T(object):
    _i = 5

    @property
    def i(self):
        return self.__class__._i

    @i.setter(self, value)
        self.__class__._i = value

当然,这不会阻止用户使用实例的
\u i
与类的
\u i
自身相分离的
.i
是正确的,并且肯定可以工作(尽管
i
是一个糟糕的命名选择)

如果访问
i
的方法不使用self,则可以将其设置为类方法,在这种情况下,第一个参数将是类而不是实例:

class T(object):
    i = 5
    @classmethod
    def p(cls):
        print cls.i

要读取属性,还可以安全地使用
self.i
。但要更改其值,使用
self.i=value
将更改实例的属性,从而屏蔽该实例的class属性

你为什么需要这个?你想实现什么?@Katrielex:那将返回对象变量,我想要类变量。@Malgree:它们是一样的。不。对象是类的实例。对不起,这可能是我使用了错误的术语,来自另一种语言——在某种程度上。那么,实例变量。属性?这是实例属性与类属性的对比。在这里,我想我的措词是对的。@Malgree:除非您将一个值作为实例的一部分专门指定给属性,否则它无论如何都会引用类所持有的对象。如果对我的对象进行子类化的开发人员使用i作为对象变量,因此涵盖了我的静态变量,则不会。是吗?@maligree:是的,我在发完帖子后意识到了这一点。从那时到现在,我都不在电脑前,所以直到现在我才更新我的帖子。实际上考虑过提到类方法,但没有考虑它们在显示类值时的用途,即使实例属性隐藏了类上的值。您还可以使用类方法从实例修改类属性,或者。。。哦,有个主意。请参阅我更新的答案。@Malgree:不鼓励对类和实例变量使用相同的名称,尤其是当类变量应该在这样的子类中可重写时。考虑到这一点,
self.i
应该是访问
self.\uuuu class\uuuu.i
的一种完全可以接受的方式。这不仅在非常特殊的情况下是正确的(例如,元类,特别是它们的一些魔法成员,或者当
self.\uuuu class\uuuu.i
是一个描述符时)。回答不错,但是,呃,我真的讨厌“klass”这个词。使用“
cls
”作为
@classmethod
的第一个参数。