2012-02-08 77 views
2

Python支持類屬性,實例屬性和屬性。什麼是初始化屬性或屬性的Pythonic方法?

from time import ctime, sleep 

class MyClass(object): 
    A = ctime()   # class attribute 
    def __init__(self): 
     self.B = ctime() # instance attribute 
     self._C = None 

    @property 
    def C(self):   # property 
     if self._C is None: 
      self._C = ctime() 
     return self._C 
    @C.setter 
    def C(self, c): 
     self._C 

爲了誰不知道一個用戶,MyClass的是如何實現的,A,B和C表現出類似的行爲:

sleep(2) 
myObject = MyClass() 
sleep(2) 
print myObject.A   # prints time module was initialized 
print myObject.B   # prints time instance was created, 2 sec later 
print myObject.C   # prints time this line was called, 2 sec later 
myObject.A = 'foo'  # myObject.A is now an instance attribute 
myObject.B = 'foo'  # myObject.B is still an instance attribute 
myObject.C = 'foo'  # myObject.C is still an (instance) property 
print myObject.A   # prints 'foo' 
print myObject.B   # prints 'foo' 
print myObject.C   # prints 'foo' 

從我來到這裏的答案,我明白了以下幾點:第一次打印myObject.AmyObject.AmyObject.__Class__.AMyClass.A。第二次myObject.A不是myObject.__Class__.A。精細。

在上面的示例中,ctime()僅用於說明A,B和C如何區別。現在假設,我們使用的是不變的常數代替:

class MyClass(object): 
    A = 'bar'    # class attribute 
    def __init__(self): 
     self.B = 'meta'  # instance attribute 
     self._C = None 

    @property 
    def C(self):   # property 
     if self._C is None: 
      self._C = 'foobar' 
     return self._C 
    @C.setter 
    def C(self, c): 
     self._C = c 

myObject = MyClass() 

myObject.A仍是類屬性MyClass.A,而myObject.B是一個實例屬性和myObject.C是一個屬性。他們所有人都按照我的意願去做。他們有一個默認值,我可以分配一些其他值。我應該使用哪種款式,A,B或C?

+1

其實他們都不是「工作」。他們不是都做同樣的事情。 'foo.A'實際上**創建**一個實例變量,它在現有的'Foo.A'類變量之前被找到。 「我應該使用哪種風格」完全取決於你的目標是什麼。你想要實例變量還是類變量?請在問題中包含您的目標。 – 2012-02-08 22:05:44

回答

1

這取決於您希望初始化運行以及您想要的實例。

  • 如果您希望在該類的所有實例之間共享該屬性的單個實例(即單個值),請使用class屬性。
  • 如果您希望類的每個實例都具有不同的屬性值,請使用實例屬性。

另外,您的代碼示例包含屬性而不是屬性。

我無法理解您對該問題的更新。您可能需要退後一步並解釋您的根本問題。

0

初始化常量類屬性的首選方法是在類定義本身中。

查看問題中的代碼,似乎對如何從實例對象訪問類屬性存在一些困惑。

請注意,在實例對象中,您可以按名稱訪問類屬性,因爲在內部字典中找不到屬性時,查找會繼續到類字典中。也就是說,如果instance.A不存在,instance.__class__.A將返回,如果它可用。

但是,當在對象實例中創建屬性時,類屬性會被遮蔽。即,instance.A = <value>會創建一個新的實例屬性,並且下次訪問instance.A時,將返回<value>。但是,班級屬性仍然可以使用instance.__class__.A進行檢索。

1

似乎有兩種創建簡單屬性或屬性的風格。

他們根本不是「風格」,而只有一件事是做的:任務。

它們有不同的效果。

在Python中,遵循邏輯規則,在class塊中聲明的內容屬於該類。因此A是該類的一個屬性(大致類似於在C++或Java或C#中聲明的static)。 B是每個實例的屬性,在實例上運行__init__時自動生成。

至於你的更新,我不知道你想問什麼。嘗試使用真實姓名而不是'A'並解釋您的使用案例(即爲什麼您想要做任何事情)。