1

I have a class Foo which contains a datamember of type Bar. I can't make a generalized, "default" Bar.__init__() - the Bar object is passed into the Foo.__init__() method.

How do I tell Python that I want a datamember of this type?


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

This works, when I pass in the "default" values as shown. However, when I call getBar, I do not get back the one I passed in in the Foo.__init__() function - I get the "default" values.


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

This spits out 0 0 0, not 1 2 3, like I'm expecting.

If I don't bother declaring the myBar variable, I get errors in the getBar(self): method (Foo instance has no attribute 'myBar').

What's the correct way to use a custom datamember in my object?

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

事前に宣言する必要はありません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

通常、変数に適切な名前を付けてセッターを省略するだけで、より「pythonic」と見なされます。

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

正しい方法は、コンストラクターで割り当てる以外に何もしないことです。

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

    def getbar(self):
        return self.bar
于 2012-08-10T14:42:51.090 に答える
1

Python では変数を宣言せず、変数は型指定されていません。

ただ行う:

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

    def getbar(self):
        return self.bar

この問題は、奇妙な古いスタイルのクラスを使用していることが原因であると思われます。オブジェクトから継承すると、新しいスタイルのクラスが得られます。これは、それほど驚くべきことではありません。

于 2012-08-10T14:47:39.060 に答える