2

クラスでメタクラスが使用されているかどうかに関係なく、定義されているすべてのクラスにデフォルトのメタクラスを使用するように python モジュールまたは REPL を構成することは可能ですか?

class met(type):
    def __init__(cls, name, bases, dct):
        super(met, cls).__init__(name, bases, dct)
        setattr(cls, "_test_member", "test_value")

class A(object):
    pass

>>> A._test_member
'test_value'
4

2 に答える 2

3

Pavel Anossov の (現在は削除された) コメントの使用:

class met(type):
    def __init__(cls, name, bases, dct):
        super(met, cls).__init__(name, bases, dct)
        cls._test_member = "test_value"

object = met('object', (object,), {})

class A(object):
    pass

print(A._test_member)

版画

test_value

クラスはメタクラスを 1 つしか持つことができないことに注意してください。(結局のところ、どのオブジェクトも 1 つのタイプしか持てないため)。さらに、クラスのメタクラスは、そのすべてのベースのメタクラスの (厳密ではない) サブクラスでなければなりません。つまり、クラスのメタクラスとそのすべてのベースのメタクラスが同じであるか、それらのメタクラスがすべて互いのサブクラスである必要があります。そのため、クラスが のサブクラスではないメタクラスを使用しようとすると、上記の解決策は機能しない可能性がありmetます。

例えば、

class met(type):
    def __init__(cls, name, bases, dct):
        super(met, cls).__init__(name, bases, dct)
        cls._test_member = "test_value"

object = met('object', (object,), {})

class someothertype(type): pass

class B(object):
    __metaclass__ = someothertype

上げる

TypeError: Error when calling the metaclass bases
    metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases
于 2013-07-05T02:52:32.137 に答える
2

Python 2.xでは、次のことができます

 __metaclass__ = met

モジュールの冒頭で、クラスを古いスタイル モードで定義します。

class A:
    pass

3.x では、これはもはや不可能です。また、「明示的は暗黙的よりも優れています。」

別のアプローチとして、次のことができます。

class Object(metaclass=met):  # Py3k syntax
    pass

そして常にそれを継承します。

注: のサブクラスを呼び出すことtypeは、Py2k と Py3k の両方と互換性のあるメタクラスを利用する唯一の方法です。unutbuの答えのように

于 2013-07-05T02:48:21.703 に答える