python类__init__方法会隐式返回None吗?
我试图在类构造函数( init )中返回一个值:
class A:
def __init__(self):
return 1
但是有一个运行时错误,说 init 应该返回None。在这种情况下,如何理解:
a=A()
其中“ a”被分配为类实例?
-
严格来说,不是
A.__new__()
创建实例a
。定义时
class A(object):
(或者class A:
如果您正在使用Python3,class A:
则也是不推荐使用的 旧
类),__new__
则从继承的继承object.__new__()
中调用创建实例a
。当
a = A()
执行时,将发生以下情况:A()
是的简写A.__call__
object.__new__(cls, *args, **kwargs)``cls=A
创建实例实际是在什么地方发生的a
。它为新对象分配内存,然后 应 返回一个新对象(实例)。- 当且仅当 返回新创建的对象不会
__init__(self)
再 得到调用传递给它的新创建的对象“用来初始化”的对象。
考虑以下演示:
-
当我们重写
__new__
并且不再返回对象时,__init__
将不会被调用:class A(object): def __new__(cls, *args, **kwargs): print cls, args, kwargs def __init__(self): self.x = 'init!' print self.x
In : a = A()
() {} note that “init!” has not appeared here because new didn’t return an
new instance
-
现在,通过使用返回一个新的实例
object.__new__
,你会看到,经过__new__
,__init__
会被称为好:class A(object): def __new__(cls, *args, **kwargs): print cls, args, kwargs return object.__new__(cls, args, kwargs) def __init__(self): self.x = 'init!' print self.x
In : a = A()
() {}
init!
这是另一个展示差异的演示,请注意,
a
无需调用即可创建实例__init__()
:class A(object): def __init__(self): self.x = "init!" print self.x In : a = object.__new__(A) In : a Out: <__main__.A at 0x103466450> In : a.__dict__ Out: {} In : aa = A() init! In : aa Out: <__main__.A at 0x1033ddf50> In : aa.__dict__ Out: {'x': 'init!'}
现在进行询问(并刷新我自己的内存=]):
粗略地说,有两种主要方法可以在Python中创建新对象:
通过子类创建新对象( type / class ):
class
语句告诉Python来创建一个新的 类型 / 类 对象(通过继承现有 类型 / 类 如object
):class Hello(object): pass >>> Hello.__class__ <type 'type'>
实际上,所有 类 / 类型 对象都具有类型
type
。type
(type(type)
)的类型仍为type。您可以将 类型 / 类 对象作为子 类 。
通过实例化创建新对象( 实例 ):
您还可以通过实例化现有的 类型 对象来创建新对象。这是通过使用
__call__
操作符(的简写()
)完成的:>>> h = hello() >>> type(h) <class '__main__.Hello'> >>> type(int('1')) <type 'int'>
您不能子类化实例对象。
(请注意,您还可以通过其他方式(例如使用list运算符)创建新的 实例 对象
[1,2,3]
,在这种情况下,它将创建一个列表实例)您可以通过
type(my_obj)
或检查对象的类型my_object.__class__
。
现在,您知道如何创建实例对象,但是 真正 创建 类型 / 类 对象(允许创建实例对象)的是什么?
实际上,这些对象也是通过实例化创建的,尽管与前面提到的实例化稍有不同。
除了
class
语句之外,您还可以type(cls_name, parent_class_tuple, attr_dict)
用来创建一个新类。例如:type('Hello', (object,), {})
将创建与
Hello
前面显示的类相同的类。什么
type
啊 输入 metaclass 。type
是一个 metaclass ,它是class的 类
,即,class是metaclasses的实例。该__class__
的type
仍然是type
。所以这是一个图,显示了 元类 , 类 , 实例 之间的关系:
instantiate instantiate metaclass --------------> class ----------------> instance type.__new__() object.__new__()
当
type
调用metaclass创建新类时,类似的流程如下:type.__call__()
被谴责type.__new__()
分配内存,然后返回一个新的类(一个元类实例),然后调用type.__init__()
。type.__init__()
初始化从步骤2传递过来的新创建的类。
您甚至可以通过子类化来创建新的元类
type
:class MyMeta(type): def __new__(meta, name, bases, dct): # do something return super(MyMeta, meta).__new__(meta, name, bases, dct) def __init__(cls, name, bases, dct): # do something super(MyMeta, cls).__init__(name, bases, dct)
那么您可以
MyMeta
像使用type
以下方法一样,从此元类创建一个新类:MyClass = MyMeta('MyClass', (object, ), {'x': 1})
或者,
__metaclass__
在定义类时使用,其效果与上面显示的效果完全相同:class MyClass(object): __metaclass__ = MyMeta x = 1