0

+=Pythonのサブクラスで使えるようにしたいです。つまり+=、Pythonでスーパークラスの値に追加できるようにしたいのです。

class a():
  a = 2
class b(a):
  a += 4

b = b()

assert b.a == 6

私はこのようにできることを知っています

class b(a):
  a = a.a + 4

しかし、私はもっと簡潔な方法でそれをやりたいと思っています。また、上記を使用できないようですsuper()

4

2 に答える 2

6

あなたがしたいことはできません。これらは、Python の設計の意図的な側面です。

これはできません:

class a():
    a = 2
class b(a):
    a += 4

a最後の行にスコープがないためです。aが見つかる名前空間について明示する必要があります。

で動作させる方法は見つかりませんsuper。その理由はsuper、パラメータとして少なくとも型が必要ですが、それを使用したい時点 ( の定義内b) にbはまだ存在しないためです。だから、あなたはそれを与えることはできませんsuper()

最後に、あなたはあなた自身の質問に答えました。明示的は暗黙的よりも優れているため、正しいことをしています。

于 2012-12-31T18:25:54.153 に答える
1

@Phil Frostは、あなたが望むように見える直接構文を使用してそれを行うことができないということは正しいです。ただし、クラスデコレータを使用することはできます。これはクラスが定義された後に実行されるため、スーパークラスの変数にアクセスできます。ただし、少し面倒な構文を使用する必要があります。1つの可能性があります:

class InheritedPlus(object):
    def __init__(self, toAdd):
        self.toAdd = toAdd

def addInherited(cls):
    for attr, val in vars(cls).iteritems():
        if isinstance(val, InheritedPlus):
            setattr(cls, attr, getattr(super(cls, cls), attr)+val.toAdd)
    return cls

class A(object):
    x = 2

@addInherited
class B(A):
    x = InheritedPlus(3)

>>> B.x
5

これでは使用できません+=が、スーパークラスの値に基づいてサブクラスにクラス属性を作成する効果を得ることができます。Inherited()もう少し賢くすれば、さまざまな演算子を実装し、オペランドを格納する汎用クラスを作成して、などを許可することができますx = Inherited() + 3

クラス定義時にスーパークラス属性にアクセスしたいという正当なユースケースがあると思いますが、このアプローチはそのために機能します。ただし、例のような単純なケースがある場合は、このレベルの複雑さの価値はおそらくないので、a.a + 4明示的に使用する必要があります。

于 2012-12-31T19:25:04.927 に答える