2012-02-16 116 views
4

兩類類屬性定義的區別?

class Foo(object): 
    bar = 1 
    def __init__(self): 
     ... etc. 

class Foo(object): 
    def __init__(self): 
     ... etc. 

Foo.bar = 1 

之間的差異在這兩種情況下,bar是類的屬性,它是同爲類的所有實例,對不對?

回答

4

我想說的是,唯一的區別是,在第二種情況下,Foo.bar而不是以前的,而在第一種情況下創建類對象時已經可以執行Foo.bar = 1聲明存在。

這可能沒有在你的代碼產生任何影響小的差異(除非有一些代碼,需要Foo.bar它在第二種情況下是可用之前)。不過,我會說第一個選項在可讀性方面更好,因爲您不必向下滾動以瞭解您班級的屬性,它們已經在那裏了。

+0

感謝,是有意義的。 – mcepl 2012-02-16 10:55:53

4

如果你正在編寫自己的代碼,請與:

class Foo(object): 
    bar = 1 

becase的這個版本:

class Foo(object): 
    pass 

Foo.bar = 1 

即使它是合法的

  1. 看起來更像是一個黑客。
  2. 在大多數情況下可讀性較差。
  3. 如果您嘗試訪問bar屬性的創建之前,您可能有問題:

    >>> class Foo: 
    ...  pass 
    ... 
    >>> f = Foo() 
    >>> f.bar 
    Traceback (most recent call last): 
        File "<stdin>", line 1, in <module> 
    AttributeError: 'Foo' object has no attribute 'bar' 
    >>> Foo.bar = 1 
    >>> f.bar # but hey, now you're ok! 
    1 
    

其他我並不認爲有很多不同之處。

-1

兩個版本是相同的(見這個答案最終的測試成績單),但要注意在兩種情況下是:(a)爲barFoo所有實例相同。

在創建一個實例的時刻,讀取所述實例bar將讀取Foo分配到Foo.bar的值,將反映在直到instance.bar被分配給該實例。在分配的那個時刻,實例獲取自己的__dict__條目,它完全獨立於該類。

In [62]: class Foo: pass 

In [63]: Foo.bar = 1 

In [64]: Foo.bar 
Out[64]: 1 

In [65]: f = Foo() 

In [66]: f.bar 
Out[66]: 1 

In [67]: f.bar +=1 

In [68]: f.bar 
Out[68]: 2 

In [69]: Foo.bar 
Out[69]: 1 

In [70]: Foo.bar +=3 

In [71]: Foo.bar 
Out[71]: 4 

In [72]: g = Foo() 

In [73]: g.bar 
Out[73]: 4 

In [74]: class Qux: bar = 1 

In [75]: Qux.bar 
Out[75]: 1 

In [76]: q = Qux() 

In [77]: q.bar 
Out[77]: 1 

In [78]: q.bar+=1 

In [79]: q.bar 
Out[79]: 2 

In [80]: Qux.bar 
Out[80]: 1 

In [81]: Qux.bar +=1 

In [82]: r = Qux() 

In [83]: r.bar 
Out[83]: 2 

In [84]: q.bar 
Out[84]: 2 

In [85]: s = Qux() 

In [87]: s.__dict__ 
Out[87]: {} 

In [88]: q.__dict__ 
Out[88]: {'bar': 2} 

In [89]: Qux.bar = 'foo' 

In [90]: Qux.bar 
Out[90]: 'foo' 

In [91]: s.bar 
Out[91]: 'foo' 
+1

-1顯然是錯誤的:「Foo」的實例不是「bar」的副本 - 它們訪問類屬性。當設置一個實例屬性時,它將獲得它自己的屬性。見我的答案在http://stackoverflow.com/questions/9302789/changing-variables-in-multiple-python-instances/9304924#9304924 – jsbueno 2012-02-16 10:52:31

+0

@jsbueno:證明這一點。該行爲看起來就像每個實例獲取類對象中的值的副本(這是指向對象的指針)。 – Marcin 2012-02-16 11:04:26

+0

@jsbueno:我已經添加了自己的證據,因爲您鏈接的答案實際上並沒有任何證據表明您的立場。 – Marcin 2012-02-16 11:12:09