Python:self vs type(self)和类变量的正确使用

时间:2014-07-24 01:33:45

标签: python class-variables

在Python中使用类变量时,可以访问并且(如果它是可变的)通过" self"直接操作它。 (感谢参考)或"键入(自我)" (直接),而当你只使用" self"时,不可变变量(例如整数)显然会被新的实例对象遮蔽。

因此,在处理Python类变量时,最好/ Pythonic是否总是使用" type(self)"用于处理类方法中引用的类变量?

(我知道类变量有时是不受欢迎的,但是当我使用它们时,我想以一致的方式访问它们(如果它们是不可变类型则采用一种方式,如果它们是可变的则采用另一种方式。)

编辑:是的,如果您修改了一个不可变的值,那么您将得到一个新对象。修改可变对象的价值的副作用是导致这个问题的原因 - " self"将为您提供一个引用,您可以使用它来更改类变量而不用遮蔽它,但是如果为它分配一个新对象,它将会遮蔽它。使用classname.classvar或type(self).classvar或self .__ class__可确保您始终使用类变量,而不仅仅是阴影它(尽管子类使这种情况复杂化,如下所述)。

4 个答案:

答案 0 :(得分:4)

您可能希望使用实际的类型名称访问它们,而不是selftype(self)

您所看到的效果与可变性无关。如果你要做

class Foo(object):
    x = []
    def __init__(self):
        self.x = [1]

__init__中的赋值将创建一个新列表并将其分配给实例属性x,忽略类属性,即使Foo.x是一个可变对象。无论何时想要分配属性,都需要使用它实际定义的对象。

请注意,在继承的情况下,通过type(self)修改属性失败:

class Foo(object):
    x = 1
    def modify_x(self, x):
        type(self).x = x

class Bar(Foo): pass

Foo().modify_x(2) # modifies Foo.x
Bar().modify_x(3) # modifies Bar.x, the wrong attribute

答案 1 :(得分:1)

python -c 'import this'
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!

我会建议这些参考

Beautiful is better than ugly.
Simple is better than complex.
Readability counts.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
If the implementation is hard to explain, it's a bad idea.

我的建议是使用直接属性引用,因为它可能是语言设计者的意图。

答案 2 :(得分:1)

在离线与其他人交谈后(根据@ wwii对此处其中一个答案的评论),事实证明最好的方法没有明确地嵌入类名是使用 self .__ class __。attribute

(虽然有些人使用type(self).attribute会导致其他问题。)

答案 3 :(得分:0)

https://bitbucket.org/larry/cpython350/pull-requests/15/issue-24912-prevent-class-assignment/diff

在通常情况下,它们的工作原理相同(可能应该使用YouClass.NameAttribute以避免以后的继承问题)。 简而言之,直到Python 3.5为止。问题是问题#24912(在所有情况下都不允许评估)。例如:像int这样的不可变类型被分配到staticalli中,并且HEAPTYPE意外地从停止 class 分配的位置停止。