6

私は2つのクラスAとBを持っています:

class A(object):
    x = 0

class B(object):
    y = 0

デコレータを使用して、 BがAのクラスレベル変数(この場合はx )を「継承」するようにするにはどうすればよいですか?それは可能ですか?装飾後の望ましい動作(可能な場合)、Bは次のようになります。

class B(object):
    x = 0
    y = 0

注:誰かが私がこれを求めている理由を知りたい/必要がある場合は、SQLAlchemyの具象テーブル継承をコードで見栄えよくするだけですが、そのような動作の多くのユースケースを見ることができます。

4

1 に答える 1

6

できますよ; クラス A を引数として取り、装飾されたクラスを更新するクラス デコレータを使用できます。

import types

class copyattributes(object):
    def __init__(self, source):
        self.source = source

    def __call__(self, target):
        for attr, value in self.source.__dict__.items():
            if attr.startswith('__'):
                continue
            if isinstance(value, (property, types.FunctionType)):
                continue
            setattr(target, attr, value)
        return target

デコレーターは、実際には (関数やプロパティではなく) 属性であり、2 つのアンダースコアで始まっていないものをすべてコピーします。

使用法:

class A(object):
    x = 0

@copyattributes(A)
class B(object):
    y = 0

プロンプトでテスト:

>>> class A(object):
...     x = 0
...
>>> @copyattributes(A)
... class B(object):
...     y = 0
... 
>>> B.y
0
>>> B.x
0
>>> dir(B)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'x', 'y']
于 2012-08-18T00:05:51.383 に答える