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 0不像 1 2 3我期待的那样。

如果我不费心声明myBar变量,我会在getBar(self):方法 ( Foo instance has no attribute 'myBar') 中得到错误。

在我的对象中使用自定义数据成员的正确方法是什么?

4

4 回答 4

7

您无需告诉 Python 您将要添加某个数据成员——只需添加它即可。在这方面,Python 比 Java 更具动态性。

如果bar实例本质上是不可变的(这意味着它们实际上不会更改),则可以将默认实例作为__init__()参数的默认值:

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

使用默认值的所有Foo实例将共享一个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

请注意,您通常不应该在 Python 中编写 getter 和 setter。它们只是降低应用程序速度的不必要的样板代码。由于 Python 支持属性,因此您也不需要它们是面向未来的。

于 2012-08-10T14:42:36.403 回答
2

正确的方法是除了在构造函数中赋值之外什么都不做。

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

    def getbar(self):
        return self.bar
于 2012-08-10T14:42:51.090 回答
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

通常,仅适当地命名变量并省略 setter 被认为更“pythonic”。

class Foo:
    def __init__(self, bar=None):
        self.bar = bar if bar else Bar(...)
于 2012-08-10T14:54:19.863 回答
1

您无需在 Python 中声明变量,并且变量是无类型的。

做就是了:

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

    def getbar(self):
        return self.bar

我怀疑这个问题是由你使用老式类引起的,这有点奇怪。如果你从 object 继承,你会得到一个新风格的类,它的设计不会那么令人惊讶。

于 2012-08-10T14:47:39.060 回答