gpt4 book ai didi

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

转载 作者:太空宇宙 更新时间:2023-11-03 11:01:00 25 4
gpt4 key购买 nike

我的类层次结构是这样设置的,所以每个 child 的 __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() 正在解析父类,但是当装饰器试图调用 super().__init__(*args, **kwargs),为什么 Python 会尝试调用 object.__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

希望这对您有所帮助!

关于python - 用 super() 装饰子类的 __init__ 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32491009/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com