python技巧图解(Python魔法方法功能与用法简介)
python技巧图解
Python魔法方法功能与用法简介本文实例讲述了python魔法方法功能与用法。分享给大家供大家参考,具体如下:
1、什么是魔法方法?
魔法方法就是可以给你的类增加魔力的特殊方法,如果你的对象实现(重载)了这些方法中的某一个,那么这个方法就会在特殊的情况下被 python 所调用,你可以定义自己想要的行为,而这一切都是自动触发的。它们经常是两个下划线包围来命名的(比如 __init__
,__lt__
),python的魔法方法是非常强大的,所以了解其使用方法也变得尤为重要!
2、__init__(self[, ...]),__new__(cls[, ...]),__del__(self)
1)__init__ 构造器,当一个实例被创建的时候初始化的方法。但是它并不是实例化调用的第一个方法,__new__才是实例化对象调用的第一个方法,它只取下 cls 参数,并把其他参数传给 __init__。 __new__很少使用,但是也有它适合的场景,尤其是当类继承自一个像元组或者字符串这样不经常改变的类型的时候。
2)__new__ 使用时注意以下四点:
- a) __new__ 是在一个对象实例化的时候所调用的第一个方法;
- b)它的第一个参数是这个类,其他的参数是用来直接传递给 __init__ 方法;
- c) __new__ 返回一个构建的实例;
- d) __new__ 决定是否要使用该 __init__ 方法,因为 __new__ 可以调用其他类的构造方法或者直接返回别的实例对象来作为本类的实例,如果 __new__ 没有返回实例对象,则__init__ 不会被调用;
- e) __new__ 主要是用于继承一个不可变的类型比如一个 tuple 或者 string。
__new__实现单例模式(无论多少次实例化,结果都是同一个实例)
单例模式(singleton pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在。当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场。
比如,某个服务器程序的配置信息存放在一个文件中,客户端通过一个 appconfig 的类来读取配置文件的信息。如果在程序运行期间,有很多地方都需要使用配置文件的内容,也就是说,很多地方都需要创建 appconfig 对象的实例,这就导致系统中存在多个 appconfig 的实例对象,而这样会严重浪费内存资源,尤其是在配置文件内容很多的情况下。事实上,类似 appconfig 这样的类,我们希望在程序运行期间只存在一个实例对象。
举例:
|
class person( object ): def __init__( self , name, age): self .name = name self .age = age def __new__( cls , * args, * * kwargs): if not hasattr ( cls , 'instance' ): cls .instance = super ().__new__( cls ) return cls .instance a = person( 'p1' , 21 ) b = person( 'p2' , 22 ) print (a = = b, a.name = = b.name) # 这里的打印结果都是true,可见 a 和 b 都是同一个实例(实例 b 覆盖了实例 a)。 # 单例作用: #第一、控制资源的使用,通过线程同步来控制资源的并发访问; #第二、控制实例产生的数量,达到节约资源的目的; #第三、作为通信媒介使用,也就是数据共享。比如,数据库连接池的设计一般采用单例模式,数据库连接是一种数据库资源。 # 应用场景: #python的logger就是一个单例模式,用以日志记录 #线程池、数据库连接池等资源池一般也用单例模式 #windows的资源管理器是一个单例模式 #网站计数器 |
3)__del__ 析构器,当实例被销毁时调用。
3、__call__(self[,args ...]),__getitem__(self,key),__setitem__(self,key,value)
1)__call__ 允许一个类的实例像函数一样被调用,如下。
|
class person( object ): def __init__( self , name, age): self .name = name self .age = age self .instance = add def __call__( self , * args): return self .instance( * args) def add(args): return args[ 0 ] + args[ 1 ] a = person( 'p1' , 20 ) print (a([ 1 , 2 ])) #这里将打印 3 #可见当创建a这个对象之后,如果定义了__call__函数则对象是可以像函数一样调用的。 |
2)__getitem__ 定义获取容器中指定元素的行为,相当于self[key]
,如下。
|
class person( object ): def __init__( self , name, age): self .name = name self .age = age self ._registry = { 'name' : name, 'age' : age } def __call__( self , * args): return self .instance( * args) def __getitem__( self , key): if key not in self ._registry.keys(): raise exception( 'please registry the key:%s first !' % (key,)) return self ._registry[key] a = person( 'p1' , 20 ) print (a[ 'name' ],a[ 'age' ]) #这里打印的是 'p1' 20 #可见__getitem__使实例可以像字典一样访问 |
3)__setitem__ 设置容器中指定元素的行为,相当于self[key] = value
。
4、__getattr__(self,name),__getattribute__(self,name),__setattr__(self,name,value),__delattr__(self,name)
1)__getattr__ ():当用户试图访问一个不存在属性时触发;
2)__getattribute__(): 当一个属性(无论存在与否)被访问时触发;
3)__setattr__ ():当一个属性被设置时触发;
4)__delattr__ ():当一个属性被删除时触发。
|
class person( object ): def __init__( self , name, age): self .name = name self .age = age self ._registry = { 'name' : name, 'age' : age } def __getattribute__( self , item): #注意此处不要再访问属性,如self.__dict__[item] #因为self.__dict__依然会被__getattribute__拦截,这样就会陷入死循环 return object .__getattribute__( self ,item) def __getattr__( self , item): print ( "don't have the attribute " ,item) return false def __setattr__( self , key, value): self .__dict__[key] = value a = person( 'p1' , 20 ) print (a.cs) #这里会打印 don't have the attribute cs 以及 false a.cs = '测试' #这里设置该属性值为'测试' print (a.cs) #这里将打印出'测试' |
希望本文所述对大家python程序设计有所帮助。
原文链接:https://www.cnblogs.com/wcwnina/p/7294257.html
- python读取数据集的图片(浅析Python 读取图像文件的性能对比)
- python怎么自动生成报告(python根据文章标题内容自动生成摘要的实例)
- python微信红包代码(php生成微信红包数组的方法)
- python里字典常用方法(Python使用字典的嵌套功能详解)
- 利用python合并pdf(Python合并同一个文件夹下所有PDF文件的方法)
- python plot绘图(python使用Plotly绘图工具绘制气泡图)
- python钉钉机器人(python钉钉机器人运维脚本监控实例)
- python自动识别旋转验证码(Python实现字符型图片验证码识别完整过程详解)
- python的条件判断和循环(对Python中的条件判断、循环以及循环的终止方法详解)
- pythonjpg转pdf格式(Python使用到第三方库PyMuPDF图片与pdf相互转换)
- python快速数据分类(Python基于滑动平均思想实现缺失数据填充的方法)
- python中迭代器的作用(Python3.5迭代器与生成器用法实例分析)
- python中tkinter模块窗口操作(详解python tkinter教程-事件绑定)
- python 微信发天气信息(python微信聊天机器人改进版定时或触发抓取天气预报、励志语录等,向好友推送)
- python如何使用multiprocess(Python multiprocessing多进程原理与应用示例)
- pythonhttp文件服务器(使用Python创建简单的HTTP服务器的方法步骤)
- 医事文化谈屑 | 古人的名 字 号(医事文化谈屑古人的名)
- ()
- 网友很惭愧,自己写了很多年的字,到头来还不如一名小学生写的好(自己写了很多年的字)
- 中华第一楷 张瑞龄 86岁高龄,苦练楷书71年,一幅字卖593万(中华第一楷张瑞龄)
- 冯骥才 年意(冯骥才年意)
- ()
热门推荐
- 数据库设计的几个建议
- mysql5.7.19下载及安装教程(Apache2.2.16+PHP5.3.3+MySQL5.1.49的配置方法)
- vue-cli请求数据的方式(vue-cli配置使用Vuex的全过程记录)
- 如何排查mysql存储过程的问题(Mysql修改存储过程相关权限问题)
- dedecms会员功能(dedecms注册中文会员无法打开空间的解决方法)
- pyinstaller打包后为什么报错(Pyinstaller打包.py生成.exe的方法和报错总结)
- sql datalength与len区别
- css3边框阴影的属性(css3 border-radius属性详解)
- dedecms手机独立域名(DedeCMS Wap.php 绑定域名的解决办法)
- nginx怎么实现反向代理(nginx反向代理时如何保持长连接)
排行榜
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9