代码之家  ›  专栏  ›  技术社区  ›  Jason Baker

在python中,type和type的区别是什么?

  •  13
  • Jason Baker  · 技术社区  · 15 年前

    class MetaCls(type):
        def __new__(cls, name, bases, dict):
            return type(name, bases, dict)
    

    …而不是这样:

    class MetaCls(type):
        def __new__(cls, name, bases, dict):
            return type.__new__(cls, name, bases, dict)
    

    这两个元类之间到底有什么区别?更具体地说,是什么导致第一个类不能正常工作(有些类没有被元类调用)?

    6 回复  |  直到 15 年前
        1
  •  12
  •   mg.    15 年前

    在第一个示例中,您将创建一个全新的类:

    >>> class MetaA(type):
    ...     def __new__(cls, name, bases, dct):
    ...         print 'MetaA.__new__'
    ...         return type(name, bases, dct)
    ...     def __init__(cls, name, bases, dct):
    ...         print 'MetaA.__init__'
    ... 
    >>> class A(object):
    ...     __metaclass__ = MetaA
    ... 
    MetaA.__new__
    >>> 
    

    在第二种情况下你打电话给父母的 __new__

    >>> class MetaA(type):
    ...     def __new__(cls, name, bases, dct):
    ...         print 'MetaA.__new__'
    ...         return type.__new__(cls, name, bases, dct)
    ...     def __init__(cls, name, bases, dct):
    ...         print 'MetaA.__init__'
    ... 
    >>> class A(object):
    ...     __metaclass__ = MetaA
    ... 
    MetaA.__new__
    MetaA.__init__
    >>> 
    
        2
  •  8
  •   polar9527    6 年前

    object.__new__() 作品。

    这是从 documentation

    object.__new__(cls[, ...])

    调用以创建类的新实例 cls . __new__() 方法(特殊大小写,因此您不必声明它) 请求实例作为其第一个参数的类。 其余的参数是传递给对象构造函数的参数 应该是新的对象实例(通常是 cls公司

    超类 __新建\() 方法使用 super(currentclass, cls).__new__(cls[, ...]) 在返回新创建的实例之前,请根据需要重新创建实例。

    __新建\() 返回的实例 ,然后是新实例 __init__() __init__(self[, ...]) ,在哪里 self 已传递给 .

    如果 __新建\() cls公司 ,然后是新实例 方法将不会被调用。

    __新建\() 主要用于允许 不变的 int , str tuple )自定义实例创建。它也是 创造。

    以毫克计 answer __init__ 后者调用函数 __初始化__ __new__ .

        3
  •  7
  •   TheJJ    10 年前

    请参考下面的注释,希望对您有所帮助。

    class MetaCls(type):
        def __new__(cls, name, bases, dict):
            # return a new type named "name",this type has nothing
            # to do with MetaCls,and MetaCl.__init__ won't be invoked
            return type(name, bases, dict)
    
    class MetaCls(type):
        def __new__(cls, name, bases, dict):
            # return a new type named "name",the returned type 
            # is an instance of cls,and cls here is "MetaCls", so 
            # the next step can invoke MetaCls.__init__ 
            return type.__new__(cls, name, bases, dict)
    
        4
  •  5
  •   bobince    15 年前
    return type(name, bases, dict)
    

    你从这里得到的是一个新的 type ,而不是 MetaCls 梅塔尔斯 __init__ )永远不会被召唤。

    type.__new__ 将被称为创建新类型的一部分,是的,但是 cls 进入这个功能将是 类型 而不是 梅塔尔斯

        5
  •  5
  •   Nishant Florentin    8 年前
    class MyMeta(type):
        def __new__(meta, cls, bases, attributes):
            print 'MyMeta.__new__'
            return type.__new__(meta, cls, bases, attributes)
        def __init__(clsobj, cls, bases, attributes):
            print 'MyMeta.__init__'
    
    class MyClass(object):
      __metaclass__ = MyMeta
      foo = 'bar'
    

    实现相同结果的另一种方法:

    cls = "MyClass"
    bases = ()
    attributes = {'foo': 'bar'}
    MyClass = MyMeta(cls, bases, attributes)
    

    MyMeta __call__

    Python将寻找 __呼叫__ 的类型(即 type 在我们的情况下)

    对于新样式的类,特殊方法的隐式调用是必需的

    MyClass = MyMeta(...) 解释为:

    my_meta_type = type(MyMeta)
    MyClass = my_meta_type.__call__(MyMeta, cls, bases, attributes)
    

    type.__call__()

    MyClass = MyMeta.__new__(MyMeta, cls, bases, attributes)
    meta_class = MyClass.__metaclass__
    meta_class.__init__(MyClass, cls, bases, attributes)
    return MyClass
    

    MyMeta.__new__() 将决定 MyClass 建造时间:

    type.__new__(meta, cls, bases, attributes) 将设置正确的元类(即 )为了 类名

    type(cls, bases, attributes) 类名

        6
  •  2
  •   Azeem.Butt    15 年前

    一切都描述得很好 here .