8

私はPythonでオブジェクト指向のコードをいくつか持っています。ここで、いくつかのクラスは、コードの欠落しているカスタムビット(テンプレートメソッドパターンだけでなく、変数も含む)を提供するために拡張されることを意図しており、スーパークラスによってのみ使用されます。それらを使用するクライアントコード。

そのような抽象(またはスーパークラスでの実装は例外を発生さpassせるため、鈍いNonImplemented)メソッドと属性のスタイル規則はありますか?

私はPEP-0008を閲覧してきましたが、サブクラスで使用することを意図していないプライベートメンバーにアンダースコアを付けることについてのみ言及しています。

4

3 に答える 3

13

私は通常、保護された (C++ のように) メソッド/属性などに単一のアンダースコアを使用_myvarします。これは、派生クラスで使用でき__var、他の人が使用しない場合などに二重アンダースコアを使用できます。また、クラス定義レベルでの二重アンダースコアの名前はmangledであるため、派生クラスでオーバーライドすることはできません。

class A(object):
    def result1(self): # public method
        return self._calc1()

    def result2(self): # public method
        return self.__calc2()

    def _calc1(self): # protected method, can be overridden in derived class
        return 'a1'

    def __calc2(self): # private can't be overridden
        return 'a2'


class B(A):
    def _calc1(self):
        return 'b1'

    def __calc2(self):
        return 'b2'

a = A()
print a.result1(),a.result2()
b = B()
print b.result1(),b.result2()

ここでは、派生クラスBが両方_calc1をオーバーライドしているようです__calc2__calc2、その名前はすでにクラス名でマングルされているため、オーバーライドされていないため、出力は

a1 a2
b1 a2

それ以外の

a1 a2
b1 b2

ただし、最終的には任意の規則を選択して文書化します。上記の場合でも、基本クラスがプライベートをオーバーライドできないわけではありません。ここに方法があります:)

class B(A):
    def _calc1(self):
        return 'b1'

    def _A__calc2(self):
        return 'b2'
于 2011-10-18T15:13:45.963 に答える
10

まず、次のように言うのは間違っていると思います。

サブクラスで使用することを意図していないプライベート メンバーにアンダースコアを追加することについて。

実際にメソッド/属性の前にアンダースコアを追加することは、このメソッド/属性がクラス (およびそのサブクラス) の外部でアクセスされるべきではないことを意味する Python の規則であり、メソッドを作成するために使用される二重アンダースコアについて読むのを忘れたと思います/attribute は上書きできません。

class Foo(object):
    def __foo(self):
        print "foo"
    def main(self):
        self.__foo()


class Bar(Foo):
    def __foo(self):
        print "bar"


bar = Bar()
bar.main()
# This will print "foo" and not "bar".

abc.ABCMetaabc.abstractmethodを使用する方法でスタブ メソッドを宣言する別の方法があります。

于 2011-10-18T15:14:13.177 に答える
2

これらのメソッドには、オーバーライドされたときに同じ名前が付けられるため、実際には命名規則はありません。そうでなければ、それらはオーバーライドされません! オーバーライドされるメソッドに些細なことをさせ、それに応じてそれを文書化するだけで十分だと思います:

class MyClass:

  def aMethod():
    '''Will be overridden in MyDerivedClass'''
    pass

質問で言及した名前マングリングは、オーバーライドされる重要なメソッドがあるが、基本バージョンにアクセスできるようにしたい場合に役立ちます。詳細と例については、ドキュメントを参照してください。

于 2011-10-18T15:15:24.587 に答える