python中init和setup有什么区别_python 中__init__与__new__的区别

图片发自简书App

旧式和新式类中的__NEW__和__INIT__

本文的目的是讨论Python的__new__和__init__方法。

该new和init方法不同的行为本身之间以及旧式与新式python类定义之间。

了解__new__和__init__之间的区别

这两种方法的主要区别是__new__处理对象创建,而__init__处理对象初始化。

在实例化过程中,如果定义不同,这两者在工作方式上略有差异。

有关Python中的类

Classes in python are classified as new-style and old-style. Old-style classes are the ones that are prior to python 3 and defined without inheriting from base class 'object', which in turn is inherited from 'type' by default.

python 2.x中的旧式类:

class A: # -> inherits from 'type'

pass

python 2.x中的新式类:

class A(object): # -> clearly inherits from 'object'

pass

In python 3 there aren't new or old styles of classes and they inherit directly from 'object' so there is no need to specify it as a base anymore.

在本文的其余部分中,我们将介绍两种情况下的 __new__和__init__方法,以确定它们的行为方式以及如何使用它们。

深度讲解

Before diving into the actual implementations you need to know that new accepts cls as it's first parameter and init accepts self, because when calling new you actually don't have an instance yet, therefore no self exists at that moment, whereas init is called after new and the instance is in place, so you can use self with it.

__new__和__init__用于旧式类

旧式类实际上并没有__new__方法,因为对于它们来说__init__是构造函数,假设如下:

class A:

def __new__(cls):

print "A.__new__ is called" # -> this is never called

A()

在这种情况下new 的主体将永远不会被执行,因为它不是老式类的目的。

如果我们要重写__init__:

class A:

def __init__(self):

print "A.__init__ called"

A()

输出将是:

A.__init__ called

现在让我们尝试从__init__返回一些东西:

class A:

def __init__(self):

return 29

A()

这会产生:

TypeError: __init__() should return None

所以这意味着我们实际上无法控制实例化旧式类时要返回的内容。

__new__和__init__用于新的样式类

新风格的类让开发人员同时覆盖__new__和__init__,他们有不同的用途,__new__ (构造函数)仅用于创建object和__init__ (初始化程序)来初始化它。

让我们看看他们的执行顺序:

class A(object): # -> don't forget the object specified as base

def __new__(cls):

print "A.__new__ called"

return super(A, cls).__new__(cls)

def __init__(self):

print "A.__init__ called"

A()

输出将是:

A.__new__ called

A.__init__ called

您可能想知道__init__或__new__在哪里被调用,而我为您准备的是__new__在调用类名(实例化时)时自动调用,而__init__在__new__每次由__new__返回时被调用,而将实例返回传递给__init__ 且self'作为参数,因此,即使您将该实例保存在全局/静态的某个位置,并且每次先都从__new__返回,每次都会调用__init__。

知道了这一点就意味着如果我们调用super的__new__,那么__init__将不会被执行。让我们来看看是不是这样的情况:

class A(object):

def __new__(cls):

print "A.__new__ called"

def __init__(self):

print "A.__init__ called" # -> is actually never called

print A()

输出是:

A.__new__ called

None

显然,实例被识别为None,因为我们不从构造函数返回任何东西。

想知道如果我们从__new__返回什么可能会发生什么?

笑脸

猜猜输出是什么:

class A(object):

def __new__(cls):

print "A.__new__ called"

return 29

print A()

让我们看看当我们从__init__返回时会发生什么:

A.__new__ called

29

这产生:

class A(object):

def __init__(self):

print "A.__init__ called"

return 33 # -> TypeError: __init__ should return None

A()

这主要是因为调用__init__的处理程序 引发了TypeError异常,并且从__init__返回任何内容都没有意义,因为它的目的只是改变新创建的实例的新状态。

看起来新型的类在灵活性方面有提高,允许我们在创建和初始化级别执行任何PRE / POST操作,并使我们控制在实例化时返回的内容。

考虑到这一点,我们试着返回一个不同类的实例。

首先我们定义一个类:

class Sample(object):

def __str__(self):

return "SAMPLE"

然后我们定义__new__覆盖类:

class A(object):

def __new__(cls):

return Sample()

这也可以写成:

class A(object):

def __new__(cls):

return super(A, cls).__new__(Sample)

然后调用:

print A()

那会输出:

SAMPLE

这里是我写的一个例子,帮助大家理解:

class Alfa(object):

def __new__(cls):

#creat a generate ,get int value by filter

#g=(x for x in range(10) if isinstance(x,int) and x <0)

print("__new__")

#return an parent instance

return super().__new__(cls)

def __init__(self):

print ("__init__")

print (id(self))#print self address at Memory

super().__init__()

#l=['a',1,2,-2,-5,8,9,0]

t=Alfa()# instantiation a object

print(id(t))#print self address at Memory

print(t)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值