使用super()装饰子类的__init__方法

我的类层次结构设置为每个子的__init __()必须将self._init_has_run()设置为False,调用父的__init __(),然后执行自己的__init __(),最后将self._init_has_run()设置为True.我有以下代码:

class Parent:
    def __init__(self, arg1, arg2):
        pass  # do stuff

    def init(cls, fun):
        def decorated_init(self, *args, **kwargs):
            self._init_has_run = False
            x = super()
            super().__init__(*args, **kwargs)
            fun(self, *args, **kwargs)
            self._init_has_run = True
        return decorated_init

class Child(Parent):
    @Parent.init
    def __init__(self, arg1, arg2):
        pass  # do stuff

由于有许多子类遵循__init __()的相同通用模式,并且我无法弄清楚如何使用元类,我使用装饰器来合并重复逻辑,然后将该装饰器应用于所有后代__init__ () 方法.

Python正在抛出以下内容:

File "filename.py", line 82, in decorated_init
super().__init__(*args, **kwargs)
TypeError: object.__init__() takes no parameters

我通过调试器确认self._init_has_run的切换工作正常,而super()正在解析为Parent类,但是当装饰器试图调用super().__ init __(* args,** kwargs)时,为什么Python会尝试调用object .__ init __()代替?

解决方法:

您可以轻松地使用元类来执行一些pre / post-init之类的东西.考虑这个例子:

class Meta(type):
    def __new__(meta, *args):
        # This is something like 'class constructor'.
        # It is called once for every new class definition.
        # It sets default value of '_init_has_run' for all new objects.
        # This is analog to `class Foo: _init_has_run = False`:
        # new objects will all have _init_has_run set to False by default.

        cls = super(Parent, meta).__new__(meta, *args)
        cls._init_has_run = False
        return cls

    def __call__(cls, *args, **kwargs):
        # This is called each time you create new object.
        # It will run new object's constructor
        # and change _init_has_run to False.

        obj = type.__call__(cls, *args, **kwargs)
        obj._init_has_run = True
        return obj


class Child:
    __metaclass__ = Meta

    def __init__(self):
        print 'init:', self._init_has_run

    def foo(self):
        print 'foo:', self._init_has_run


a = Child()
a.foo()

a = Child()
a.foo()

输出:

init: False
foo: True
init: False
foo: True

希望这可以帮助!

上一篇:Java Vector(扩容细节)


下一篇:【Java集合】ArrayList类 扩容机制 底层源码分析