にサブクラス化、私はこのクラスを持っていると言う:メンバーリストへの追加のPython
class FooClass(object):
foos = ["foo", "bar"]
def do_foos(self):
for foo in self.foos:
print("I have a " + foo)
# ...
私は(すなわちfoos
に項目"spec"
を追加し、FooClass
を拡張し、このクラスのSpecialisedFooClassを作成したいfoos
が含まれるように、 ["foo", "bar", "spec"]
)。
SpecialisedFooClass.foos
はFooClass.foos
に依存すべき:foos
が含まれているので、私はFooClass
"の定義を変更した場合["foo", "bam", "bat"]
、SpecialisedFooClass.foos
は、["foo", "bam", "bat", "spec"]
が含まれている必要があります。
これは私がこれまでに作ってみた最善の方法である:
class SpecialisedFooClass(FooClass):
foos = FooClass.foos + ["spec"]
しかし、私はに関するFooClass
への明示的な参照を見つけます。仲介サブクラスを追加することにしたとき(つまり、SpecialisedFooClass
'スーパークラスが変更されたとき)、私は必然的にこのリファレンスを更新することを忘れてしまいます。私は実際に私が作業しているコードベース(これは実際にはのfoos、bams、およびbatsを扱わない...)でこのエラーIRLを実際に作っています。
は実際にfoos
は、クラスのメンバではなく、インスタンスのメンバであることを私の場合には特別な要件はありませんので、これも動作しますが、私はそれが醜い見つけます。また、super
コールには明示的なクラス参照があります。なぜなら、そのクラスに表示されるためです。
class FooClass(object):
def __init__(self, *args, **kwargs):
self.foos = ["foo", "bar"]
def do_foos(self):
for foo in self.foos:
print("I have a " + foo)
class SpecialisedFooClass(FooClass):
def __init__(self, *args, **kwargs):
super(SpecialisedFooClass, self).__init__(*args, **kwargs)
self.foos.append("spec")
他のどのようなオプションが存在し、これを行うには、「Python的」な方法はありますか? fooのリストを取得するためにインスタンス化する必要はありませんので、クラスメソッドに変換
class A(object):
foo_ = ['a']
@classmethod
def foo(cls):
return sum((getattr(c, 'foo_', []) for c in cls.__mro__[::-1]), [])
class B(A):
foo_ = ['b']
class C(B):
foo_ = ['c','d','e']
class D(A):
foo_ = ['f', 'g', 'h']
class E(B,D):
foo_ = ['i', 'j', 'k']
for cls in (A,B,C,D,E):
print cls.__name__, cls.foo()
プリント
A ['a']
B ['a', 'b']
C ['a', 'b', 'c', 'd', 'e']
D ['a', 'f', 'g', 'h']
E ['a', 'f', 'g', 'h', 'b', 'i', 'j', 'k']
EDIT
:
メタクラスのアプローチは涼しく、それを考えなかったでしょう! – Bahrom
この小さな例では、それはおそらく保証されませんが、これがちょうど氷山の先端であれば、それは意味をなさないかもしれません。 –
別のオプションクラスのデコレータが追加されました。 –