Python - 从实例访问类变量

时间:2014-08-29 23:40:36

标签: python

我有这堂课:

class ReallyLongClassName:

    static_var = 5

    def instance_method(self):
        ReallyLongClassName.static_var += 1

有没有办法使用自变量访问静态变量?我宁愿做class(self).static_var += 1之类的事情,因为长名字是不可读的。

2 个答案:

答案 0 :(得分:51)

使用self.__class__.classAttr。这适用于旧的和新风格的课程。

答案 1 :(得分:37)

答案是“是的,但......”

理解的最佳方式是实际尝试:

>>> class RLCN:
...     static_var = 5
...     def method1(self):
...         RLCN.static_var += 1
...     def method2(self):
...         self.static_var += 1
>>> rlcn = RLCN()
>>> RLCN.static_var, rlcn.static_var
(5, 5)
>>> rlcn.static_var
5
>>> rlcn.method1()
>>> RLCN.static_var, rlcn.static_var
(6, 6)
>>> rlcn.method2()
>>> RLCN.static_var, rlcn.static_var
(6, 7)

发生了什么事?

好吧,通过self访问一个类属性就可以了。如果没有相同名称的实例属性,则获取class属性。

为其分配将使用同名的新实例属性隐藏class属性。这可能不是你想要的。

请注意,这意味着您可以将类属性用作实例属性的“默认值”或“初始值”。但我不确定这样做是非常Pythonic的;实际发生了什么,以及新手(特别是来自C ++ 11或Java的人)认为正在发生的事情,是非常不同的。

(当你处理描述符时,事情变得稍微复杂一些,比如方法或@property s,但是让我们忽略它;在你正在讨论的简单情况下,它是不相关的。)


  

我宁愿做类似课程(自我).static_var + = 1,因为长名字是不可读的。

你可以,你只需要拼写正确:type是返回任何对象类型的函数。所以:

type(self).static_var += 1

这具有动态的附加优势(例如,当您有多个继承并且不知道@property来自哪一方时,您可能不希望显式列出类名,基本上您希望使用super()而不是显式调用基类方法的原因相同。

这样做的缺点是不能在Python 2.x中使用旧式类,但是你不应该使用它们。特别是在需要类属性的类中,因为这些类型正是您以后经常要添加@classmethod@property等等的类型,而且这些类型都不起作用与旧式课程(以及许多其他事情)。如果您确实需要出于某种原因透明地处理旧式和新式类,self.__class__适用于旧式类。我不确定它是否可以保证与新式课程一起工作;文档说type(object)的返回值“通常与object.__class__返回的对象相同”,但没有说“在什么条件下”“一般”是不真实的。它也被记录为3.x中的special attribute "added by the implementation" for "several object types"。在实践中,我不知道它们在3.x中是不同的任何情况,而在2.x中,最显着的情况是它们不同的是旧式的类。