Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/357.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 元类调用vs基类新___Python_Oop_Metaprogramming - Fatal编程技术网

Python 元类调用vs基类新__

Python 元类调用vs基类新__,python,oop,metaprogramming,Python,Oop,Metaprogramming,我想知道基类的\uuuuu new\uuuu和元类的\uuuu call\uuuuuu之间的区别 考虑以下示例代码: class Metaclass(type): def __call__(cls, *args): print("Metaclass.__call__", cls, args) obj = type.__call__(cls, *args) return obj # cls.__init__ was already called class Dem

我想知道基类的
\uuuuu new\uuuu
和元类的
\uuuu call\uuuuuu
之间的区别

考虑以下示例代码:

class Metaclass(type):
  def __call__(cls, *args):
    print("Metaclass.__call__", cls, args)
    obj = type.__call__(cls, *args)
    return obj  # cls.__init__ was already called


class DemoWithMetaclass(metaclass=Metaclass):
  def __init__(self, x):
    print("DemoWithMetaclass.__init__", x)
    self.x = x


class Baseclass(object):
  def __new__(cls, *args):
    print("Baseclass.__new__", cls, args)
    obj = super(Baseclass, cls).__new__(cls)
    return obj  # cls.__init__ not yet called


class DemoWithBaseclass(Baseclass):
  def __init__(self, x):
    print("DemoWithBaseclass.__init__", x)
    self.x = x


demo1 = DemoWithMetaclass(1)
print("got:", demo1, demo1.x)

demo2 = DemoWithBaseclass(2)
print("got:", demo2, demo2.x)
产出将是:

Metaclass.__call__ <class '__main__.DemoWithMetaclass'> (1,)
DemoWithMetaclass.__init__ 1
got: <__main__.DemoWithMetaclass object at 0x103b2cb90> 1
Baseclass.__new__ <class '__main__.DemoWithBaseclass'> (2,)
DemoWithBaseclass.__init__ 2
got: <__main__.DemoWithBaseclass object at 0x103b34e10> 2
元类。调用(1,)
DemoWithMetaclass.\uuuu初始化\uuuuu1
得到:1
基类。新的(2,)
DemoWithBaseclass.\uuuu初始化\uuuuu2
得到:2
一个区别是,通过基类
\uuuuu new\uuuuuu
,您无法翻译参数或类似的内容。 根据用例的不同,这可能是一个微小的或不相关的差异。 元类通过其
\uuuu new\uuuu
\uuuu prepare\uuuuu
提供进一步的元编程

两者都可以用来实现单例。 在某些情况下,当您使用基类
\uuuuuu new\uuuu
返回现有实例时,将对已经存在的实例调用
\uuuuu init\uuuu
,该实例之前已经调用过
\uuuuu init\uuuu
,因此您可能需要特别注意这一点

还有其他区别吗?或者,假设我们不需要任何其他元编程功能,为什么只在基类上使用元类呢