默认类型__call__是否比调用__new__和__init__还要多? [英] Does the default type.__call__ do more than call __new__ and __init__?

查看:76
本文介绍了默认类型__call__是否比调用__new__和__init__还要多?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个元类,并且我想在__new__和__init__之间调用一个附加方法.

I'm writing a metaclass, and I want an additional method to be called between __new__ and __init__.

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

If I were calling the method before __new__ or after __init__ I could write e.g.

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__的功能.但是我担心键入可能会有些微妙.__call__我已经省略了,这将在实现我的元类时导致意外的行为.

and just reproduce the functionality of type.__call__ myself. But I'm afraid there might be some subtlety to type.__call__ I have omitted, which will lead to unexpected behavior when my metaclass is implemented.

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

I cannot call extraMethod from __init__ or __new__ because I want users of my metaclass to be able to override __init__ and __new__ as in normal Python classes, but to still execute important set-up code in extraMethod.

谢谢!

推荐答案

如果您确实希望按照您所说的去做,我可以建议您使用以下解决方案:

If you really wish to do exactly what you said I can suggest you the following solution:

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()

此代码将产生以下结果:

This code will generate the following result:

new
custom_method
init

这篇关于默认类型__call__是否比调用__new__和__init__还要多?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆