python中的魔法方法__new___032.Python魔术方法__new__和单态模式

一 __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

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值