2012-08-10 98 views
1

我有一個類Foo其中包含Bar類型的數據項。我無法制作一個廣義的「默認」Bar.__init__() - 將Bar對象傳遞給Foo.__init__()方法。聲明類對象數據類型

如何告訴Python我想要這種類型的數據倉庫?


class Foo: 

# These are the other things I've tried, with their errors  
    myBar   # NameError: name 'myBar' is not defined 
    Bar myBar  # Java style: this is invalid Python syntax. 
    myBar = None #Assign "None", assign the real value in __init__. Doesn't work 
##### 

    myBar = Bar(0,0,0) # Pass in "default" values. 
    def __init__(self, theBar): 
     self.myBar = theBar 

    def getBar(self): 
     return self.myBar 

這個工作,當我傳入「默認」的值如圖所示。但是,當我打電話getBar,我做而不是找回我在Foo.__init__()函數中通過的一個 - 我得到「默認」值。


b = Bar(1,2,3) 
f = Foo(b) 
print f.getBar().a, f.getBar().b, f.getBar().c 

該吐出0 0 01 2 3,就像我期待的。

如果我不打擾聲明myBar變量,我在getBar(self):方法(Foo instance has no attribute 'myBar')中出現錯誤。

什麼是在我的對象中使用自定義數據存儲的正確方法?

+2

聽起來像這個問題是你的Bar類而不是Foo。那是什麼課程? – 2012-08-10 14:41:17

回答

7

您不需要告訴Python您要添加某個數據成員 - 只需添加它即可。 Python比例如動態更具動態性Java在這方面。

如果bar情況下基本上是不可變的(意味着它們在實踐中沒有發生變化),你可以給默認實例作爲__init__()參數的默認值:

class Foo: 
    def __init__(self, the_bar=Bar(0,0,0)): 
     self.my_bar = the_bar 

所有Foo實例uisng默認值將分享單個Bar實例。如果Bar情況可能會改變,這可能不是你想要的,你應該在這種情況下使用這個成語:

class Foo: 
    def __init__(self, the_bar=None): 
     if the_bar is None: 
      the_bar = Bar(0,0,0) 
     self.my_bar = the_bar 

請注意,你不應該平時寫getter和setter Python編寫的。它們只是不必要的樣板代碼,會降低您的應用程序。由於Python支持屬性,因此您也不需要它們成爲面向未來的。

+0

我不知道在Python中不使用getter/setter - 謝謝。 – simont 2012-08-10 14:45:38

+3

@simont:請參閱http://dirtsimple.org/2004/12/python-is-not-java.html瞭解更多關於Python中的Javaisms的內容。 – 2012-08-10 14:55:23

2

正確的方法是除了在構造函數中賦值之外別無其他。

class Foo: 
    def __init__(self, bar):              
     self.bar = bar 

    def getbar(self): 
     return self.bar 
+5

,而更正確的方法根本就不是'getbar()'方法。 – Duncan 2012-08-10 14:44:13

1

你不用Python聲明變量,變量是無類型的。

只要做到:

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

    def getbar(self): 
     return self.bar 

我懷疑,這個問題是由你使用老式類,這是一種奇怪而引起的。如果你從對象繼承,你會得到一個新式的類,這個類被設計得不那麼令人驚訝。

+0

「新風格」與「舊風格」類別是什麼意思(你會介意給他們添加一些文檔鏈接)? – simont 2012-08-10 14:49:01

+1

@simont Python有兩種類型的類,舊式和新式。在明確表示舊式的半成品黑客正在引發每個人的問題後,新增了一些類。從您對文檔的請求中,我認爲您尚未找到語言參考:http://docs.python.org/reference/datamodel.html#new-style-and-classic-class – Marcin 2012-08-10 14:56:43

2

您絕對不必提前申報bar

這聽起來像你想Foo.bar默認的值,如果沒有指定的,所以你可能會做這樣的事情:

class Foo: 
    def __init__(self, bar=None): 
     # one of many ways to construct a new 
     # default Bar if one isn't provided: 
     self._bar = bar if bar else Bar(...) 

    @property 
    def bar(self): 
     """ 
     This isn't necessary but you can provide proper getters and setters 
     if you prefer. 

     """ 
     return self._bar 

    @bar.setter 
    def bar(self, newbar): 
     """ 
     Example of defining a setter 
     """ 
     return self._bar = newbar 

通常,恰當地命名變量,忽略二傳手被認爲更加詳細「Python化」。

class Foo: 
    def __init__(self, bar=None): 
     self.bar = bar if bar else Bar(...)