Python中new与装饰器

课件:new方法、描述符、装饰器

课件:new方法、描述符、装饰器知识点一:__ new __1、单例模式(难点)知识点二:(闭包)装饰器(重、难点)知识点三:内置装饰器

知识点一:__ new __

__ new __ (cls[,...])的参数,__ new __ 方法的第一个参数是这个类,而其余的参数会在调用成功后全部传递给 __ init __ 方法初始化。

所以, __ new __ 方法(第一个执行)先于 __ init __ 方法执行:

我们比较两个方法的参数,可以发现new方法是传入类(cls),而init方法传入类的实例化对象(self),而有意思的是,__ new __ 方法返回的值就是一个实例化对象(ps:如果new方法返回None,则init方法不会被执行,并且返回值只能调用父类中的new方法,而不能调用毫无关系的类的new方法)。

classBase:

def__init__(self):

print('这是初始化方法里面')

def__new__(cls,*args,**kwargs):

print('这个cls是:',cls)# cls 就是Base类

print('这是在new方法里面')

returnobject.__new__(cls)# 必须有返回值

#实例的时候会先调用_new_方法,然后再调用初始化方法

test=Base()

1、单例模式(难点)

单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在。当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场。

比如,某个服务器程序的配置信息存放在一个文件中,客户端通过一个 AppConfig 的类来读取配置文件的信息。如果在程序运行期间,有很多地方都需要使用配置文件的内容,也就是说,很多地方都需要创建 AppConfig 对象的实例,这就导致系统中存在多个 AppConfig 的实例对象,而这样会严重浪费内存资源,尤其是在配置文件内容很多的情况下。事实上,类似 AppConfig 这样的类,我们希望在程序运行期间只存在一个实例对象。

在 Python 中,我们可以用多种方法来实现单例模式

classPerson:

pass

xiaoming=Person()

xiaohong=Person()

print(id(xiaoming))

print(id(xiaohong))地址是不是都是不一样的

# 单例模式要实现的效果就是--- 每一次实例化所创建的实例都是同一个,内存地址都是一样的

classA:

_instance=None# 实例

def__new__(cls,*args,**kwargs):

ifcls._instance==None:

cls._instance=object.__new__(cls)

returncls._instance

else:

returncls._instance

a=A()

b=A()

print(id(a))

print(id(b))

----------------------------------

classPerson:

def__new__(cls,*args,**kwargs):# self 实例本身   cls 类本身

ifnothasattr(cls,'instance'):

cls.instance=super().__new__(cls)

returncls.instance


def__init__(self,name):

self.name=name

xiaoming=Person('小明')

laowang=Person('老王')

print(id(xiaoming))

print(id(laowang))

print(laowang.name)

print(xiaoming.name)

单例的运用:任务管理器  回收站  项目日志  多线程的线程池的设计一般也是采用单例模式

知识点二:(闭包)装饰器(重、难点)

# 装饰器

# 闭包的应用

# 写函数

defouter():

a=2

definner():

print(a)

returninner# 返回来的是函数体

概念:不改变原有函数的基础上,给函数增加一些新的功能

deffunc():

print('__正在登陆__')# 登陆功能,不改变增加验证功能

defmodify(func):

defwrapper():

result=func()

returnresult+',讨厌'

returnwrapper

@modify

defgirl():

return'死鬼'

a=girl()

print(a)

知识点三:内置装饰器

classRectangles:

name='bbbb'

def__init__(self,length,width):

self.length=length

self.width=width

defarea(self):

areas=self.length*self.width

returnareas

@property# 就像访问属性一样  调用可以不用括号

defareas(self):

returnself.width*self.length

@staticmethod# 静态方法  和class类断开联系  不加self

deffunc():# self  在调用的时候会报错

print('staticmethod func')

@classmethod# 类方法 传递类本身  直接类方法

defshow(cls):# cls 代表类本身

print(cls.name)

print('show fun')

a1=Rectangles(20,30)

print(a1.area())

print(a1.areas)# 装饰器 property

Rectangles.func()# 不用实例化,不能使用类属性和方法,类中的函数

Rectangles.show()# 不用实例化,可以使用类属性和方法

类当做装饰器必须使用 __ call __

classTest_Class:

def__init__(self,func):

self.func=func

def__call__(self,*args,**kwargs):

print('类----cal----')

returnself.func()

@Test_Class

deffun_test():

print('这是个测试函数')

fun_test()

作业:代码运行时间案例

importtime

defrun_time(func):

defnew_fun(*args,**kwargs):

t0=time.time()

back=func(*args,**kwargs)

print('函数运行的时间: %s'%(time.time()-t0))

returnback

returnnew_fun

@run_time

defaaa():

time.sleep(5)

aaa()

使用装饰器计算下type()函数和isinstance()函数哪个函数执行的速度更快

print(isinstance(100,int))

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容