2011-03-09 19 views
1

チェッククラス属性が指定されたクラスで定義されているか、導出された場合

class A: 
    foo = 1 

class B: 
    foo = 2 

class C: 
    foo = 3 

class D(A, B, C): 
    pass 

def collect_foo(cls): 
    import inspect 
    foos = [] 
    for c in inspect.getmro(cls): 
     if hasattr(c, 'foo'): 
      foos.append(c.foo) 
    return foos 

collect_foo(D)戻り[1, 1, 2, 3]から1DAからそれを引き出すと倍増しています。問題は - 一意になる方法foo sです。私の心に来た最初のことは、プロパティが特定のクラスで派生されたか宣言されているかどうかをチェックすることでした。どうやってするか?

+0

これは厄介なことです。なぜあなたはそれをやっていますか? – katrielalex

+0

また、 'set(collect_foo(D))'はあなたが望むことをしますか? – katrielalex

+0

私は約100のクラスを書く必要があります。クラスの中には、「Class1(Feature1、Feature2)」や「Class2(Feature2、Feature1337)」などの特定の構成があります。私が上書きするのではなく、混在して派生クラスで利用できるような属性がいくつかあります。そのため、 'Feature'クラスの1つでは、継承階層からすべてを集めるメソッドを提供しています。 それは悪いことではありません。何かが実装に依存しない、バージョンに依存しない(2.x/3.xでも)とよく書かれているのであれば、それは厄介なハックとは言えません。 – Mikoskay

答えて

4

私はこれがうまくいくと思います...それがクラスの__dict__属性にあるかどうかを見てください。しかし、あなたが本当にこれを最初にしたいと思っていることを確認してください。

例:

if name in cls.__dict__: 
    # ... your code here ... 
    pass 
+0

正確ではないが、私が探していたSvenの答えにかなり近い。 – Mikoskay

+1

@Mikoskay:私は実際に私の答えに大きな違いは見られません。 –

7

だけ属性がc自体に定義されている場合にのみTrueが得られます

'foo' in c.__dict__ 

代わりの

hasattr(c, 'foo') 

をご確認ください。

+0

パーフェクト、ありがとう。 – Mikoskay

+1

クラスに__slots__がある場合は失敗しますので、両方を確認してください。 –

1

これは、どのような名前空間のマングリング正確

「ものがあるが、私はオーバーライドが、中で混合し、派生クラスで利用可能なことしたくないいくつかの属性ている」でありますPythonではそうです。このようにオーバーライドすべきではない属性は、2つのアンダースコアで始まる必要があります。そうすることで、彼らはオーバーライドされずに各クラスに固有のままになります。

0

私は受け入れ答えに同意するが、@classmethodが私の場合と一致しませんでした...

は、私はそれが便利な基底クラスのコンテキストからクラス辞書をチェックしたり、ミックスインした。ここで、特定のメソッドがオーバーライドされている場合など、派生クラスに適用される場合は、コードパスを実行するだけです。

すなわち(パイソン3.6):以下のように
if method_name in self.__class__.__dict__.keys(): # do something

私はそれを合理化。

  1. self
  2. __class__インスタンスの実際のタイプ
  3. したがって、辞書のみ実際に派生クラスでオーバーライドされたメソッドが含まれていることであるインスタンスです。
関連する問題