【问题标题】:Access class variable from instance从实例访问类变量
【发布时间】:2014-08-29 23:40:35
【问题描述】:

我有这门课:

class ReallyLongClassName:

    static_var = 5

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

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

【问题讨论】:

    标签: python


    【解决方案1】:

    使用self.__class__.classAttr。这应该适用于新旧样式类。

    【讨论】:

    • 这比type(self)好吗?
    • @Alexey 在 stackoverflow.com/a/25577642/5241481 上查看 cmets
    • 请不要被赞成票说服,self.__class__ 非常不符合pythonic,使用type(self) 应该是这样做的方法(如果你不希望类名硬编码)作为由stackoverflow.com/a/25577642/860421 说明。唯一需要谨慎的情况是,当您在继承类中访问超类的属性并且属性名称以__ 开头(但不结尾)时,因为名称修改会困扰您。无论如何,使用硬编码的类名是最安全的方法。
    【解决方案2】:

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

    最好的理解方法是实际尝试:

    >>> 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 的类属性工作得很好。如果没有同名的实例属性,则获取类属性。

    但是分配给它会隐藏具有同名新实例属性的类属性。这可能不是您想要的。

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

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


    我宁愿做类似 class(self).static_var += 1 之类的东西,因为长名称不可读。

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

    type(self).static_var += 1
    

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

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

    【讨论】:

    • 看来type(self).static_var += 1只适用于Python3。
    • @AntonSavin:不,它在 Python 2 中运行良好。在 Python 2.7.2 中查看 here
    • @AntonSavin:如果你使用老式的类,当然,type 不起作用,而且所有相关的好处都变得无关紧要,因为super@property,多重继承等无论如何都不适用于旧式类。但答案很简单:不要使用旧式类。但我会为此添加评论。
    • 很好的解释..唯一的缺点是如果在创建类后更改类名,那么类本身对旧类名的所有引用都需要更改....
    • 在赋值时将类变量提升为实例变量是否有一个公认的名称?在谷歌上搜索method2 中发生的事情的解释很难。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-20
    • 1970-01-01
    • 2022-08-11
    • 2011-02-21
    • 2011-05-11
    • 2012-05-21
    相关资源
    最近更新 更多