Python 从实例访问类变量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25577578/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Access class variable from instance
提问by Hyman
I have this class:
我有这门课:
class ReallyLongClassName:
static_var = 5
def instance_method(self):
ReallyLongClassName.static_var += 1
Is there some way to access the static variable using the self variable? I'd rather do something like class(self).static_var += 1, because long names are unreadable.
有没有办法使用 self 变量访问静态变量?我宁愿做类似的事情class(self).static_var += 1,因为长名称不可读。
采纳答案by Judah Meek
Use self.__class__.classAttr. This should work for both old & new style classes.
使用self.__class__.classAttr. 这应该适用于新旧样式类。
回答by abarnert
The answer is "yes, but…"
答案是“是的,但是……”
The best way to understand is to actually try it:
最好的理解方法是实际尝试:
>>> 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)
What happened?
发生了什么?
Well, accessinga class attribute through selfworks just fine. If there is no instance attribute of the same name, you get the class attribute.
好吧,通过访问类属性self工作得很好。如果没有同名的实例属性,您将获得类属性。
But assigningto it will hide the class attribute with a new instance attribute of the same name. Which is probably not what you wanted.
但是分配给它会隐藏具有相同名称的新实例属性的类属性。这可能不是您想要的。
Note that this means you can use class attributes as "default values" or "initial values" for instance attributes. But I'm not sure it's very Pythonic to do so; what's actually happening, and what a novice (especially someone coming from, e.g., C++11 or Java) thinksis happening, are very different.
请注意,这意味着您可以将类属性用作实例属性的“默认值”或“初始值”。但我不确定这样做是否非常 Pythonic;实际发生的事情与新手(尤其是来自 C++11 或 Java 的人)认为正在发生的事情大不相同。
(Things get slightly more complicated when you deal with descriptors, like methods or @propertys, but let's ignore that; in the simple case that you're discussing, it's not relevant.)
(当您处理描述符(例如方法或@propertys)时,事情会变得稍微复杂一些,但让我们忽略它;在您正在讨论的简单情况下,它无关紧要。)
I'd rather do something like class(self).static_var += 1, because long names are unreadable.
我宁愿做类似 class(self).static_var += 1 的事情,因为长名称不可读。
You can, you just need to spell it right: typeis the function that returns the type of any object. So:
你可以,你只需要拼写正确:type是返回任何对象类型的函数。所以:
type(self).static_var += 1
This has the added advantage of being dynamic (e.g., when you have multiple inheritance and don't know which side a @propertycomes from, you probably don't want to explicitly list a class name, for basically the same reason you want to use super()instead of explicitly calling a base class method).
这具有动态的(例如,当你有多重继承,不知道哪一方添加的优势@property来自于,你可能不希望明确列出一个类名,基本上是相同的原因,你要使用super()替代显式调用基类方法)。
This has the disadvantage of not working on old-style classes in Python 2.x, but then you shouldn't be using those anyway. Especially in classes that have a need for class attributes, because those are exactly the types you're often going to later want to add @classmethods, @propertys, etc. to, and none of that works with old-style classes (along with many other things). If you really need to handle old-style and new-style classes transparently for some reason, self.__class__is works with old-style classes. I'm not sure it's guaranteed to work with new-style classes; the docs say that the return value of type(object)is "generally the same object as returned by object.__class__", but doesn't say under what conditions that "generally" is untrue. It's also documented as a special attribute "added by the implementation" for "several object types"in 3.x. In practice, I don't know of any cases where they're different in 3.x, and in 2.x, the most prominent case where they're different is old-style classes.
这样做的缺点是不能处理 Python 2.x 中的旧式类,但无论如何您都不应该使用这些类。尤其是在需要类属性的类中,因为这些正是您以后经常想要添加@classmethods、@propertys 等的类型,而这些都不适用于旧式类(以及许多其他类型)事物)。如果您出于某种原因确实需要透明地处理旧式和新式类,self.__class__则可以使用旧式类。我不确定它是否保证适用于新型类;文档说 的返回值type(object)“通常与object.__class__”返回的对象相同,但没有说明在什么条件下“通常”是不真实的。它也被记录为3.x 中“几种对象类型”的特殊属性“由实现添加”。在实践中,我不知道它们在 3.x 和 2.x 中的任何不同情况,它们不同的最突出的情况是旧式类。

