5

属性aに格納されているインスタンス化時に単一のパラメーターを取るクラスがあります。_a多くのメソッド (演算子)_bについては、結果に属性も設定する必要があります。これは現在、簡単な方法で実装されています。

class SomeClass(object):
    def __init__(self, a=0):
        self._a = a
        self._b = 0

    def __add__(self, other):
        result = self.__class__()
        result._b = self._a + other._a
        return result

現在、や_bなど、のようなメンバーが多数あるため、これらの属性ごとに追加の行が必要になります。オブジェクトのインスタンス化でこれらを渡すことができると、よりクリーンなコードになります。_c_d__add__

class SomeClass(object):
    def __init__(self, a=0, _b=0):
        self._a = a
        self._b = 0

    def __add__(self, other):
        return self.__class__(_b=self._a + other._a)

aただし、 as_bを除くすべてのパラメーターの値をユーザーに渡すことは望ましくなく、_c実装_dの仕様です。複数の引数を渡さないように docstring で簡単に述べることができます。「プライベート」属性の前にアンダースコアを付けるのは、これを反映するためです。

別の方法として、2 番目のプライベート コンストラクターを提供することで、ユーザーが誤動作しにくくすることもできます。

class SomeClass(object):
    def __init__(self, a=0):
        self._a = a
        self._init()

    def _init(self, _b=0):
        self._b = _b

    @classmethod
    def _constructor(cls, a, _b):
        obj = cls(a)
        obj._init(b)
        return obj

    def __add__(self, other):
        return self.__class__._constructor(_b=self._a + other._a)

これはかなり厄介な解決策だと思います。

この問題を解決するための好ましい方法は何ですか? 他のよりエレガントなソリューションはありますか? これは本当に問題ですか。最初のオプションを使用して、さらにコード行を追加する必要がありますか?

4

2 に答える 2

7

アンダー_スコアの規則は明確であり、python の世界全体に広まっています。

「パブリック」属性を文書化し、アンダースコア付きのデフォルト引数を__init__メソッドに使用するだけです。複雑にしないでおく。

いずれにせよ、誰かがこれらのプライベート パラメーターを使用してクラスを台無しにしたい場合、Python ではなく、それらを停止するつもりはありません。

于 2013-01-06T11:04:14.360 に答える
0

少し整理するために、_b前に設定できます__init__

class SomeClass(object):
    _b = 0
    def __init__(self, a=0):
        self._a = a

    def __add__(self, other):
        result = self.__class__()
        result._b = self._a + other._a
        return result

または、プライベート変数が山ほどある場合は、それらをリストに入れて魔法をかけますか?

class SomeClass(object):
    calculated_vars = ['_b'] # All your calculated variables

    def __init__(self, a=0):
        self._a = a

    def __getattr__(self, k):
        if k in self.calculated_vars:
            return 0 # Default value for calculated variables
        else:
            raise AttributeError('{} not found'.format(k))

    def __add__(self, other):
        result = self.__class__()
        result._b = self._a + other._a
        return result

if __name__ == '__main__':
    i = SomeClass(1)
    print '_a attr: ', i._a # 1
    print '_b attr: ', i._b # 0 (Default value)
    print '_c attr: ', i._c # AttributeError: _c not found

    i2 = SomeClass(3)
    i3 = i + i2
    print '_b attr: ', i3._b # 4 (Calculated value)
于 2013-01-06T11:12:53.693 に答える