2012-08-10 99 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(...)