簡體   English   中英

Python:self vs type(self)和類變量的正確使用

[英]Python: self vs type(self) and the proper use of class variables

在Python中使用類變量時,可以通過“ self”(由於引用)或“ type(self)”(直接)訪問和(如果是可變的)直接操作它,而顯然不可變變量(例如整數)會得到當您僅使用“自我”時,新實例對象就會遮蔽。

因此,在處理Python類變量時,是否總是只使用“ type(self)”來處理從類方法中引用的類變量,是否更可取/ Pythonic?

(我知道類變量有時會被皺眉,但是當我使用它們時,我想以一致的方式訪問它們(如果它們是不可變類型,則使用一種方法,如果是可變類型,則使用另一種方法。)

編輯:是的,如果將值修改為不可變,則會得到一個新對象。 修改可變對象的值的副作用是導致此問題的原因-“自我”將為您提供一個引用,您可以使用該引用來更改類變量而不會對其進行陰影處理,但是如果您為其分配一個新對象,則會對其進行陰影處理它。 使用classname.classvar或type(self).classvar或self .__ class__可以確保您始終在使用類變量,而不僅僅是對其進行陰影處理(盡管如下所述,子類使此過程變得復雜)。

您可能需要使用實際的類型名稱訪問它們,而不是使用selftype(self)

您看到的效果與可變性無關。 如果你要做

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

__init__的賦值將創建一個新列表,並將其分配給實例屬性x ,而忽略class屬性,即使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
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.

我的建議是使用直接屬性引用,因為這可能是語言設計人員想要的。

在與其他人離線交談之后(並根據@wwii對此處答案之一的評論),事實證明,在顯式嵌入類名的情況下執行此操作的最佳方法是使用self .__ class __。attribute

(盡管那里有些人使用type(self)。歸因會導致其他問題。)

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

在通常情況下,它們的工作原理相同(可能應該使用YouClass.NameAttribute以避免以后的繼承問題)。 簡而言之,直到Python 3.5為止。 問題是問題#24912(在所有情況下都不允許評估)。 示例:像int這樣的不可變類型被分配給staticalli,並且HEAPTYPE意外地在停止降低分配的位置進行規則。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM