python - 默认类型 .__call__ 是否比调用 __new__ 和 __init__ 做的更多?

标签 python metaclass

我正在编写一个元类,我希望在 __new__ 和 __init__ 之间调用一个额外的方法。

如果我在 __new__ 之前或 __init__ 之后调用方法,我可以这样写

class Meta(type):
    def __call__(cls):
        ret = type.__call__()
        ret.extraMethod()

我的诱惑是写作

class Meta(type):
    def __call__(cls):
        ret = cls.__new__(cls)
        ret.extraMethod()
        ret.__init__()
        return ret

然后自己重​​现 type.__call__ 的功能。但是我担心 type.__call__ 可能会有一些微妙之处,我已经省略了,这将导致在实现我的元类时出现意外行为。

我不能从 __init__ 或 __new__ 调用 extraMethod,因为我希望我的元类的用户能够像在普通 Python 类中一样覆盖 __init__ 和 __new__,但仍能在 extraMethod 中执行重要的设置代码。

谢谢!

最佳答案

如果您真的想按照您所说的去做,我可以建议您采用以下解决方案:

def call_after(callback, is_method=False):
    def _decorator(func):
        def _func(*args, **kwargs):
            result = func(*args, **kwargs)
            callback_args = (result, ) if is_method else ()
            callback(*callback_args)
            return result
        return _func
    return _decorator


class Meta(type):

    def __new__(mcs, class_name, mro, attributes):
        new_class = super().__new__(mcs, class_name, mro, attributes)
        new_class.__new__ = call_after(
            new_class.custom_method,
            is_method=True
        )(new_class.__new__)
        return new_class


class Example(object, metaclass=Meta):

    def __new__(cls, *args, **kwargs):
        print('new')
        return super().__new__(cls, *args, **kwargs)

    def __init__(self):
        print('init')

    def custom_method(self):
        print('custom_method')


if __name__ == '__main__':
    Example()

此代码将生成以下结果:

new
custom_method
init

关于python - 默认类型 .__call__ 是否比调用 __new__ 和 __init__ 做的更多?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22083327/

相关文章:

python - 在类的类方法中调用 super() 以获取元类方法

python - 将基类添加到python中的现有对象

python - 当我们使用自定义函数对 groupby 结果应用时,不会传递所有列

python - 将多列添加到python中的sqlite数据库

python - Ubuntu 相当于 msvcrt 中的 getch 函数

Python 在不重新输入函数参数的情况下覆盖函数/方法

python - __instancecheck__ - 覆盖显示无效 - 我做错了什么?

python - 从 Django 中的表名中查找模型实例

python - 在 Python 中加载格式化二进制文件的最有效方法

python uiautomator 类型错误 : 'AutomatorDeviceObject' object is not callable