2011-01-19 8 views
3

私は自分のコードを整理するために言語に組み込まれた構造を使いたいと思っています。しかし、私は一貫性を保つことができない1つの状況があります。なぜなら、私はそれを行う最良の最善の方法を見ていないからです。それは、サポートクラス、つまり他のクラスによって内部的に使用されるクラスに関するものです:それらを内部クラスにするか、クラスを分離するかです。Pythonスタイルの質問:クラスを内部クラスとしてサポートしていますか?

内部クラス:

class Complicated: 
    class Utility1: 
     pass 
    class Utility2: 
     pass 
    pass 

別々のクラス:

class Complicated: 
    pass 

class Utility1: 
    pass 

class Utility2: 
    pass 

内部クラスは、それらを使用する唯一のクラス内にスコープされるという利点があります。しかし、問題は、インデントのためにコードを書くスペースが少なくなることです。

外部クラスには利点も欠点もありません。私はサポートクラスを書くたびに、いつも精神的なエネルギーを費やすことに飽き飽きし、このばかげた問題について疑問を抱いています。

私の質問は、背中に相当なパイソン経験を持つ人がこれに関するベストプラクティスがあるかどうかをアドバイスできますか?その答えが「それは頼りになる」と答えても、それは自分自身よりも経験豊かな人がいれば分かります。

答えて

6

私は

class Complicated: 
    pass 

class _Utility1: 
    pass 

class _Utility2: 
    pass 

を示唆していると、独自のモジュールでこのすべてを置きます。先頭の_は、ユーティリティクラスが内部使用のみを目的としていることを示しています(そして、それは何のためにも、from module import *によってインポートされませんが、私はこれを好きではありません)。

編集:PEP 8からの引用:内部使用のために

クラスは、ほかに先頭にアンダースコアを持っています。

+0

好みはのために '' __all__'上_'接頭辞のはなぜ? –

+1

@Joe Wreschnig: '__all__'は' from module import * 'のみに関係するので、私はとにかく使用しません。主要な '_'はPythonの内部使用インジケータです(http://www.python.org/dev/peps/pep-0008/)。 –

1

私は、Pythonパッケージの内部クラスである接頭辞として単一のアンダースコアを使用します。私はこれが一般的なのpythonパターンだと思う:

class Complicated: 
    pass 

class _Utility1: 
    pass 

class _Utility2: 
    pass 
+0

なぜ '_'の優先順位は' __all__'の前に置かれますか? –

+0

@Joe:メンテナンスの頭痛であるので、決して '__all__'を定義しません。私は、Python標準ライブラリとオープンソースプロジェクトの多くのモジュールが先頭のアンダースコアを使用してそれをコピーしていることに気付きました。私は内部(例えば '__dict__'オブジェクト)を公開し、それらを乱用しないようにプログラマーの規律に依存する多くのPythonに適合していると思います。 –

0

私は内部クラスや外部クラスを使用するかどうかは、主に私は、サブクラスまたはインスタンスごとにどちらかのタイプを上書きすることを期待するかどうかによって異なります。

class Foo(object): 
    normalize = str 

    def process(self, input): 
     # Do some stuff in here... 
     return self.normalize(output) 

class UniFoo(Foo): 
    normalize = unicode 

class TotallyMungedFoo(Foo): 
    class normalize(object): ... 

このような動作が必要ない(または明示的に望ましくない)場合は、同じモジュール内でクラスを使用しますが、__all__宣言に「重要」なものだけを含めます。

+0

'Foo'を他のクラスの基本クラスにすることを意味しましたか? – Duncan

+0

はい、私はしました!ありがとう。 –

0

Pythonの内部クラス

Pythonの内部クラスを作成して使用することも可能です。 Javaのような他の言語とは異なり、Pythonの内部クラスは自動的に外部クラスの属性やメソッドにアクセスすることはありません。

この問題の回避策: すべての内部クラスを親パラメータで定義します。このパラメータは、外部クラスの属性とメソッドにアクセスするために使用できます。

内部クラスとPythonの例クラス

class Outer: 
    def __init__(self): 
     self.myVar = 100 
     self.inner = self.Inner(self) 

    def getDoubleVar(self): 
     return(self.myVar * 2) 

    #Define inner class 
    class Inner: 
     def __init__(self, parent): 
      self.parent = parent 

     #Use the parent variable to access parent class attributes/methods 
     def printOuterVar(self): 
      print(self.parent.myVar) 

     def callOuterMethod(self): 
      return(self.parent.getDoubleVar()) 




#Create Instance of Outer Class 
outer = Outer() 

#Display myVar 
print("Display myVar") 
print(outer.myVar) 


#Execute Outer Method 
print("\nExecute Outer Method") 
print("val = outer.getDoubleVar()") 
val = outer.getDoubleVar() 
print("val: {0}".format(val)) 

#Execute Inner Method 
print("\nExecute Inner Method") 
print("outer.inner.printOuterVar()") 
outer.inner.printOuterVar() 

#Execute Inner Method That Calls Outer Method 
print("\nExecute Inner Method That Calls Outer Method") 
val = outer.inner.callOuterMethod() 
print("val = outer.inner.callOuterMethod()") 
print("val: {0}".format(val)) 

#Create Instance of Inner Class Separately 
print("\nInstantiate Inner Class Separately") 
#Note that you provide the current outer instance as the parent parameter 
print("Note that you provide the current outer instance as the parent parameter") 
print("myInner = outer.Inner(outer)") 
myInner = outer.Inner(outer) 

#Call Inner Method 
print("\nCall Inner Method") 
print("myInner.printOuterVar()") 
myInner.printOuterVar() 
print("finished") 
関連する問題