在python中,类型和类型的区别是什么?
我在写一个元类,不小心这样做了:在python中,类型和类型的区别是什么?,python,types,new-operator,metaclass,Python,Types,New Operator,Metaclass,我在写一个元类,不小心这样做了: 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) MyClass = MyMeta
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)
MyClass = MyMeta.__new__(MyMeta, cls, bases, attributes)
meta_class = MyClass.__metaclass__
meta_class.__init__(MyClass, cls, bases, attributes)
return MyClass
…而不是像这样:
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)
MyClass = MyMeta.__new__(MyMeta, cls, bases, attributes)
meta_class = MyClass.__metaclass__
meta_class.__init__(MyClass, cls, bases, attributes)
return MyClass
这两个元类之间到底有什么区别?更具体地说,是什么导致第一个类不能正常工作(某些类没有被元类调用)?描述得很好 如果没有返回正确类型的对象,那么定义自定义元类就没有意义
return type(name, bases, dict)
您从中得到的是一个新的类型
,而不是一个MetaCls
实例。因此,MetaCls
(包括\uuuu init\uuuu
)中定义的方法永远无法调用
type.\uuuuu new\uuuuu
将作为创建新类型的一部分被调用,是的,但是进入该函数的cls
的值将是type
而不是MetaCls
,在第一个示例中,您正在创建一个全新的类:
>>> 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__
>>>
在第二种情况下,您正在调用父级的\uuuu new\uuuu
:
>>> 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__
>>>
实现相同结果的另一种方法:
cls = "MyClass"
bases = ()
attributes = {'foo': 'bar'}
MyClass = MyMeta(cls, bases, attributes)
MyMeta
是可调用的,因此Python将使用特殊的方法\uuuuuuu调用\uuuuuu
Python将在MyMeta
的类型中查找\uuuuuu调用
(在我们的例子中是type
)
对于新样式的类,特殊方法的隐式调用是
只有在对象的类型上定义时才能保证正常工作,而不是
在对象的实例字典中“
MyClass=MyMeta(…)
被解释为:
my_meta_type = type(MyMeta)
MyClass = my_meta_type.__call__(MyMeta, cls, bases, attributes)
在类型中。\uuu call\uuuu()
我想象如下:
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)
MyClass = MyMeta.__new__(MyMeta, cls, bases, attributes)
meta_class = MyClass.__metaclass__
meta_class.__init__(MyClass, cls, bases, attributes)
return MyClass
MyMeta.\uuuuu new\uuuuuu()
将决定如何构建MyClass
:
type.\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
type(cls、base、attributes)
将为MyClass
设置默认元类(即type),请参考下面的注释,希望这有帮助
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)
首先需要弄清楚对象是如何工作的
这是下面的内容:
object.\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
调用以创建类cls
的新实例<代码>\uuuu new\uuuuu()是一个静态
采用
请求实例作为其第一个参数的类。
其余参数是传递给对象构造函数的参数
表达式(对类的调用)。\uuuu new\uuuu()的返回值
应该是新对象实例(通常是cls
的实例)
典型的实现通过调用
超类的\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu()方法使用super(currentclass,cls)。\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
在返回新创建的实例之前,请根据需要将其删除
如果\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
已传递给\uuuu new\uuuu()
如果\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
\uuuu new\uuuu()
主要用于允许不可变类型的子类(如int
、str
或tuple
)自定义实例创建。也是
通常在自定义元类中重写以自定义类
创造
因此,在mg's中,前者不调用函数\uuuu init\uuuuu
,而后者在调用\uuu new\uuuuuu后调用函数\uuuu init\uuuuu
,但这就是我想问的问题:为什么键入的对象不正确?我知道我必须使用子类的\uuu new\uuu
方法,但是这与使用类型有什么不同?类型如何神奇地知道你想要它生成什么类型的对象?因为我告诉了它。我输入了名称、基数和dict。我还需要提供哪些其他信息?类型是如何与对象相关的?我没有得到那部分。OP问的是关于类型的问题。它创建了一个类,而不是对象。它创建了一个类的实例。请看关于类类型(对象)的文档,我想这可能是类型和对象之间的关系。如果你明白了,记得取消你的否决票,谢谢!您(@Nishant,@rlat)需要弄清楚的是Python的类型和对象是什么,下面是答案;因此类型之间没有区别。与对象相关。对于python3类A(对象,元类=MetaA):pass
。class A作用域中的\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。但这里你指的是类名。