2011-10-18 8 views
6

私はPythonでオブジェクト指向のコードをいくつか持っていますが、いくつかのクラスはコードの欠けているカスタムビットを提供するために拡張されています(la Template Method pattern、スーパークラスでのみ使用され、クライアントコードでは使用されません。 (スーパークラスでの実装はpassのいずれかまたはNonImplemented例外引き上げるため、または鈍い)メソッドと属性を属性とメソッドのPython命名規則を上書きしようとしています

は、このような抽象的なための任意のスタイル規則はありますか?

私はPEP-0008をブラウズしていましたが、サブクラスで使用されることを意図していないプライベートメンバーに下線を付けることについてのみ言及しています。

+1

慣習は、私が知る限り、クラスのドキュメントストリングに文書化することです。それ以外の特別な規約はないと思います。 –

答えて

9

まず私はあなたがいることを言うときあなたは間違っていると思います:プライベートメンバーにアンダースコア先頭に追加程度

が意図していませんサブクラスで使用される

実際にはアンダースコアでメソッド/属性を付加すると、このメソッド/属性は、クラス(およびそのサブクラス)外部からアクセスしてはならないという意味ではPythonの慣習であると私はあなたがその2つの下線について読むことを忘れてしまったと思いますメソッド/属性をオーバーライドできないようにするために使用されます。

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を使用している方法でスタブメソッドを宣言する別の方法があります。

11

通常、単一のアンダースコアを使用します。 _myvar(C++のように)派生クラスで使用され、二重アンダースコアを使用するメソッド/属性の保護。 __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は、その名前がす​​でにクラス名を持つマングルされているので、出力は

a1 a2 
b1 a2 

代わりの

であるため、上書きされていない _calc1__calc2が、 __calc2の両方をオーバーライドしているようです
a1 a2 
b1 b2 

最終的にはいかなる慣習も選択して文書化しますトンベースクラスがプライベートオーバーライドすることはできません、ここでの方法です:)すべての

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

    def _A__calc2(self): 
     return 'b2' 
2

これらのメソッドの名前付け規則は、オーバーライド時に同じ名前になるため実際にはありません。それ以外の場合はオーバーライドされません!私はオーバーライドするメソッドを持つ些細な何かをし、それに応じてそれを文書化すると思いますが、十分に良いです:あなたは意志非自明な方法を持っている場合は、あなたの質問に言及

class MyClass: 

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

名前マングリング、有用であり、オーバーライドされますが、依然としてベースバージョンにアクセスできるようにする必要があります。詳細と例については、the documentationを参照してください。

関連する問題