一 __new__ 魔术方法
1.1 介绍
触发时机:实例化类生成对象的时候触发(触发时机在__init__之前)
功能:控制对象的创建过程
参数:至少一个cls接受当前的类,其他根据情况决定
返回值:通常返回对象或None
对象.属性
对象.方法()
类.属性
类.方法()
1.2 基本用法
classMyClass():
abc= 123
def __new__(cls): #把class这个类传递__new__这个方法print (123)returnNone #返回一个None#实例化对象
obj =MyClass()print (obj)
执行
这样就不能使用使用obj这个对象调用abc的值
classMyClass():
abc= 123
def __new__(cls):print (123)returnNone#实例化对象
obj =MyClass()print(obj)print (obj.abc) #在这里就相当于使用None.abc.这种此写法不允许,就会报错
执行
借助父类创建对象
返回本类对象
classMyClass():
abc= 123
def __new__(cls):
print (cls)print (123)#要借助父类object的__new__创建对象
obj = object.__new__(cls)returnobj#实例化对象
obj =MyClass()print(obj)print (obj.abc)
执行
[root@node10 python]# python3 test.py
#cls是一个类
123
123[root
返回空对象
classMyClass():
abc= 123
def __new__(cls):print(cls)print (123)#要借助父类object的__new__创建对象
obj = object.__new__(cls)#return obj
returnNone#实例化对象
obj =MyClass()print(obj)print (obj.abc)
执行
返回一个其他类的对象
classMyClass2():
ccc= 4obj2=MyClass2()classMyClass():
abc= 123
def __new__(cls):print(cls)print (123)#要借助父类object的__new__创建对象
obj = object.__new__(cls)#return obj
#return None
returnobj2#实例化对象
obj =MyClass()print(obj)print (obj.abc)
执行
修改属性
[root@node10 python]#cat test.py
classMyClass2():
ccc= 4obj2=MyClass2()classMyClass():
abc= 123
def __new__(cls):print(cls)print (123)#要借助父类object的__new__创建对象
obj = object.__new__(cls)#return obj
#return None
returnobj2#实例化对象
obj =MyClass()print(obj)print (obj.ccc)
执行
[root@node10 python]#python3 test.py
123
4
1.3 对__new__和__init__这两个魔术方法的区别
调用的顺序
classBoat():def __new__(cls):print (1)return object.__new__(cls)def __init__(self):print (2)
obj=Boat()print (obj)
执行
[root@node10 python]#python3 test.py
1
2
先调用__new__在调用__init__
调用和定义的顺序无关
classBoat():def __init__(self):print (2)def __new__(cls):print (1)return object.__new__(cls)
obj=Boat()print (obj)
执行
[root@node10 python]#python3 test.py
1
2
结果一样
__new__ 的触发时机要快于 __init__
__new__是用来创建对象的__init__是用来初始化对象的
先得有对象
才能初始化对象
new 和 init 他门的参数要保持一致.
1.4 如果返回的不是一个本类对象__init__就不会触发
classBoat():def __new__(cls):print (1)#return object.__new__(cls)
returnNonedef __init__(self):print (2)
obj=Boat()print (obj)
执行
[root@node10 python]#python3 test.py
1None
初始化参数
classBoat():def __new__(cls):print (1)return object.__new__(cls)#return None
def __init__(self,name):
self.name=name
obj= Boat("John")print (obj.name)
执行
[root@node10 python]#python3 test.py
Traceback (most recent call last):
File"test.py", line 8, in obj= Boat("John")
TypeError:__new__() takes 1 positional argument but 2 were given
这是因为,__new__先于__init__调用,但是,在调用的时候,已经传递了一个类(cls)的参数,name的参数就不能对应报错
classBoat():def __new__(cls,name):print (1)return object.__new__(cls)#return None
def __init__(self,name):
self.name=name
obj= Boat("John")print (obj.name)
执行,而可以调用
[root@node10 python]#python3 test.py
1John
1.5 使用参数的普通参数和关键字实参
lass Boat():def __new__(cls,*args,**kwargs):print (1)return object.__new__(cls)#return None
def __init__(self,*args,**kwargs):
strvar= ""
for i inargs:
strvar+= i + " "
print(strvar)print(kwargs)
obj= Boat("John","Jim","Tom",name="David")
执行
[root@node10 python]#python3 test.py
1John Jim Tom
{'name': 'David'}
1.6 如果__new__魔术方法返回的时其他类的对象,不会触发__init__ 本类的魔术方法
classMyClass2():
ccc= 4obj2=MyClass2()classBoat():def __new__(cls,*args,**kwargs):print (1)#return object.__new__(cls)
returnobj2def __init__(self,*args,**kwargs):print (111)
obj= Boat("John","Jim","Tom",name="David")print (obj.ccc)
执行
[root@node10 python]#python3 test.py
1
4
二 单态模式
无论实例化类几次,都有且只有一个对象.为了节省内存空间
2.1 创建一个类,实例化三个对象
[root@node10 python]#cat test.py
classSingleton():passobj1=Singleton()print(obj1)
obj2=Singleton()print(obj2)
obj3=Singleton()print (obj3)
执行
[root@node10 python]#python3 test.py
可以看到占用不同的内存空间
2.2 使用单态模式
classSingleton():#创建一个私有的对象,类外无法调用
__obj =None#定义一个方法
def __new__(cls):#判断这个对象是否为None对象
if cls.__obj isNone:
obj= object.__new__(cls) #如果是,就重新创建一个新的对象
cls.__obj =obj #把这新的对象夫给类的私有方法return cls.__obj #如果不是None,直接返回obj1=Singleton()print(obj1)
obj2=Singleton()print(obj2)
obj3=Singleton()print (obj3)
执行
[root@node10 python]#python3 test.py
发现三个对象都是一个内存地址
2.3 实际的含义,对象和init之间的关系
classSingleton():#创建一个私有的对象,类外无法调用
__obj =None#定义一个方法
def __new__(cls,name):#判断这个对象是否为None对象
if cls.__obj isNone:
cls.__obj = object.__new__(cls)return cls.__obj
def __init__(self,name):
self.name=name
obj1= Singleton("John")
obj2= Singleton("Frnak")print(obj1.name)print (obj2.name)
执行
[root@node10 python]#python3 test.py
Frnak
Frnak