Python元类与对象实例化一起使用

时间:2015-11-12 16:59:32

标签: python python-2.7

使用以下代码,我希望输出为:

# meta.__new__
# meta.__new__
# meta.__init__
# Before instantiation of Entity
# meta.__call__
# __new__
# __init__
# __call__
#

相反,我得到了以下输出:

# meta.__new__
# meta.__new__
# meta.__init__
# Before instantiation of Entity
# meta.__call__
# __new__
# __init__
# Traceback (most recent call last):
#    File "test.py", line 39, in <module>
#       e(3,4)
# TypeError: 'NoneType' object is not callable

class MyMetaClass(type):
    def __new__(cls, name, bases, dct):
        print 'meta.__new__'
        return super(MyMetaClass, cls).__new__(cls, name, bases, dct)

    def __init__(cls, name, bases, dct):
        print 'meta.__init__'
        super(MyMetaClass, cls).__init__(name, bases, dct)

    def __call__(self, *more):
        print 'meta.__call__'
        super(MyMetaClass, self).__call__(*more)

class Entity(object):
    __metaclass__ = MyMetaClass

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

    def __init__(self, x, y):
        print '__init__'
        self.x, self.y = x, y

    def __call__(self, x, y):
        print '__call__'
        self.x, self.y = x, y

if __name__ == '__main__':
    print 'Before instantiation of Entity'
    e = Entity(1,2)
    e(3,4)

1 个答案:

答案 0 :(得分:1)

请注意,在MyMetaClass.__call__的创建和实例化时调用的e实际上并未返回任何内容,因此事后e is None。因此, minimal 修复程序为:

class MyMetaClass(type):

    ...

    def __call__(self, *more):
        print 'meta.__call__'
        return super(MyMetaClass, self).__call__(*more)
      # ^ add return

但是,如果没有为什么的解释,您已经在元类上实现了__new____init__以及__call__,包括一个不太抽象的示例,它& #39;很难提供有关最合适的修复内容的建议。