python init方法是不是隐藏方法_python类init方法是否隐式返回None?

严格地说,创建实例的不是A.__new__()。

当您定义class A(object):(或者class A:,如果您使用Python3,class A:是old-style class that has been deprecated)时,它是__new__来自被调用来创建实例a的继承object.__new__()。

当执行a = A()时,将发生以下情况:A()是A.__call__的简写

object.__new__(cls, *args, **kwargs)其中cls=A,是在hood下实际发生的创建实例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!

下面是另一个演示来显示差异,请注意,可以在不调用__init__()的情况下创建实例a:class A(object):

def __init__(self):

self.x = "init!"

print self.x

In : a = object.__new__(A)

In : a

Out: <__main__.a at>

In : a.__dict__

Out: {}

In : aa = A()

init!

In : aa

Out: <__main__.a at>

In : aa.__dict__

Out: {'x': 'init!'}

现在对于好奇的人(也为了刷新我自己的记忆=):

粗略地说,在Python中创建新对象的方法主要有两种:

通过子类化创建新对象(type/class)

class语句告诉Python创建一个新的类型/类对象(通过

子类化现有的类型/类例如object):class Hello(object):

pass

>>> Hello.__class__

实际上,所有类/类型对象都有类型type。类型type

(type(type))仍然是类型。

您可以子类化一个类型/类对象。

通过实例化创建新对象(实例):

还可以通过设置现有的类型对象来创建新对象。

这是通过使用__call__运算符(缩写为())完成的:>>> h = hello()

>>> type(h)

>>> type(int('1'))

不能对实例对象进行子类划分。

(注意,您还可以通过其他方法创建一个新的实例对象,例如

正如使用列表运算符[1,2,3],在本例中,它创建一个列表实例)

可以通过type(my_obj)或my_object.__class__检查对象的类型。

现在您知道了实例对象是如何创建的,但是真正的创建类型/类对象(允许创建实例对象)的是什么?

实际上,这些对象也是通过实例化创建的,尽管它是

与前面提到的稍有不同的实例化类型。

除了class语句之外,还可以使用

type(cls_name, parent_class_tuple, attr_dict)创建一个新类。

例如:type('Hello', (object,), {})

将创建与前面所示相同的Hello类。

什么是type?输入元类。

type是一个元类,它是类的类,即

元类的实例。type的__class__仍然是type。

这是一个图表,显示了元类和类之间的关系,

实例:instantiate instantiate

metaclass --------------> class ----------------> instance

type.__new__() object.__new__()

当调用元类type来创建一个新类时,类似的流程如下:type.__call__()被执行

type.__new__()分配内存,然后返回新的一个类(一个元类instace),然后调用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__,它正好具有

与上面所示的效果相同:

^{p页r 10}$

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值