做推广网站排名,工商管理网站,网站开发的软硬件环境,网站开发公司云鲸互创怎么联系__new__() 方法的特性#xff1a;
__new__() 方法是在类准备将自身实例化时调用。__new__() 方法始终都是类的静态方法#xff0c;即使没有被加上静态方法装饰器。类的实例化和它的构造方法通常都是这个样子#xff1a;
class MyClass(object):def __init__(self, *args, *…__new__() 方法的特性
__new__() 方法是在类准备将自身实例化时调用。__new__() 方法始终都是类的静态方法即使没有被加上静态方法装饰器。类的实例化和它的构造方法通常都是这个样子
class MyClass(object):def __init__(self, *args, **kwargs):...# 实例化
myclass MyClass(*args, **kwargs) 正如以上所示一个类可以有多个位置参数和多个命名参数而在实例化开始之后在调用 __init__() 方法之前Python 首先调用 __new__() 方法
def __new__(cls, *args, **kwargs):... 第一个参数cls是当前正在实例化的类。
如果要得到当前类的实例应当在当前类中的 __new__() 方法语句中调用当前类的父类的 __new__() 方法。例如如果当前类是直接继承自 object那当前类的 __new__() 方法返回的对象应该为
def __new__(cls, *args, **kwargs):...return object.__new__(cls) 注意 事实上如果新式类中没有重写__new__()方法即在定义新式类时没有重新定义__new__()时Python默认是调用该类的直接父类的__new__()方法来构造该类的实例如果该类的父类也没有重写__new__()那么将一直按此规矩追溯至object的__new__()方法因为object是所有新式类的基类。 而如果新式类中重写了__new__()方法那么你可以自由选择任意一个的其他的新式类必定要是新式类只有新式类必定都有__new__()因为所有新式类都是object的后代而经典类则没有__new__()方法的__new__()方法来制造实例包括这个新式类的所有前代类和后代类只要它们不会造成递归死循环。具体看以下代码解释 class Foo(object):def __init__(self, *args, **kwargs):...def __new__(cls, *args, **kwargs):return object.__new__(cls, *args, **kwargs) # 以上return等同于
# return object.__new__(Foo, *args, **kwargs)
# return Stranger.__new__(cls, *args, **kwargs)
# return Child.__new__(cls, *args, **kwargs)class Child(Foo):def __new__(cls, *args, **kwargs):return object.__new__(cls, *args, **kwargs)
# 如果Child中没有定义__new__()方法那么会自动调用其父类的__new__()方法来制造实例即 Foo.__new__(cls, *args, **kwargs)。
# 在任何新式类的__new__()方法不能调用自身的__new__()来制造实例因为这会造成死循环。因此必须避免类似以下的写法
# 在Foo中避免return Foo.__new__(cls, *args, **kwargs)或return cls.__new__(cls, *args, **kwargs)。Child同理。
# 使用object或者没有血缘关系的新式类的__new__()是安全的但是如果是在有继承关系的两个类之间应避免互调造成死循环例如:(Foo)return Child.__new__(cls), (Child)return Foo.__new__(cls)。
class Stranger(object):...
# 在制造Stranger实例时会自动调用 object.__new__(cls) 通常来说新式类开始实例化时__new__()方法会返回clscls指代当前类的实例然后该类的__init__()方法作为构造方法会接收这个实例即self作为自己的第一个参数然后依次传入__new__()方法中接收的位置参数和命名参数。注意如果__new__()没有返回cls即当前类的实例那么当前类的__init__()方法是不会被调用的。如果__new__()返回其他类新式类或经典类均可的实例那么只会调用被返回的那个类的构造方法。 class Foo(object):def __init__(self, *args, **kwargs):...def __new__(cls, *args, **kwargs):return object.__new__(Stranger, *args, **kwargs) class Stranger(object):...foo Foo()
print type(foo) # 打印的结果显示foo其实是Stranger类的实例。# 因此可以这么描述__new__()和__ini__()的区别在新式类中__new__()才是真正的实例化方法为类提供外壳制造出实例框架然后调用该框架内的构造方法__init__()使其丰满。
# 如果以建房子做比喻__new__()方法负责开发地皮打下地基并将原料存放在工地。而__init__()方法负责从工地取材料建造出地皮开发招标书中规定的大楼__init__()负责大楼的细节设计建造装修使其可交付给客户。 单例的作用就是为了节约系统资源,每每生成一个对象的时候都回去占用内存空间,因此单例就可以结局这个问题
#非单例模式,非单例模式在每次实例化的时候都会去调用内存生,这样调用的次数多了,就可能会造成内存的浪费class A(object):passaA()
bA()
print(id(a))
print(id(b))输出结果
3000151570976
3000151571312#单例模式
#讲解:在类开始之前会调用类的new方法去生成一个对象,所以我们只需要在类调用钱做处理就好了
class B(object):__instrance None #定义一个变量def __new__(cls):if cls.__instrance None:cls.__instrance object.__new__(cls) #如果变量是None说明是第一次调用,就生成一个对象,return cls.__instranceelse:return cls.__instrance #如果不是就直接返回上次生成好了的对象cB()
dB()
print(id(c))
print(id(d))输出结果
3000151571592
3000151571592#instrance :实例
总结
__new__至少要有一个参数cls代表要实例化的类此参数在实例化时由Python解释器自动提供
__new__必须要有返回值返回实例化出来的实例这点在自己实现__new__时要特别注意可以return父类__new__出来的实例或者直接是object的__new__出来的实例
__init__有一个参数self就是这个__new__返回的实例__init__在__new__的基础上可以完成一些其它初始化的动作__init__不需要返回值
我们可以将类比作制造商__new__方法就是前期的原材料购买环节__init__方法就是在有原材料的基础上加工初始化商品环节 参考自http://www.cnblogs.com/ifantastic/p/3175735.html