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协程详解(为什么你还不懂得怎么使用Python协程)
- python 从入门到实践笔记(python基础梳理一推荐)
- python如何用md5作为文档名(Python生成MD5值的两种方法实例分析)
- 用python如何写tkinter(浅谈python3.6的tkinter运行问题)
- python代码添加微信号(python 获取微信好友列表的方法微信web)
- python正则表达式入门(Python正则表达式实现简易计算器功能示例)
- 浅谈Python3中strip()、lstrip()、rstrip()用法详解(浅谈Python3中strip、lstrip、rstrip用法详解)
- python多进程与多线程详解(Python线程之定位与销毁的实现)
- python实现网络爬虫的步骤(Python实现的爬取小说爬虫功能示例)
- python里import的是什么(python中import与from方法总结推荐)
- 用python画圣诞树送给女朋友(情人节快乐! python绘制漂亮玫瑰花)
- python如何使用multiprocess(Python multiprocessing多进程原理与应用示例)
- python数据分析用到的模块(python模块之subprocess模块级方法的使用)
- python函数式编程源码(python仿evething的文件搜索器实例代码)
- 苏志燮赵恩静结婚,韩国四大公共财产变三人,这么快就有替补了(苏志燮赵恩静结婚)
- 《内在美》后,一大波新韩剧来袭,李钟硕朴信惠宋慧乔玄彬回归(一大波新韩剧来袭)
- 给孩子选购保温杯,注意这4个步骤,比颜值更重要(给孩子选购保温杯)
- 保温好 容量大 颜值高 保温杯你给娃娃买对了吗(保温好容量大颜值高)
- 《道德经》 人生避开骄狂,才能免去祸患(道德经人生避开骄狂)
- 郭麒麟(郭麒麟)
热门推荐
- 多个tomcat实例配置文件(tomcat单机多实例的实现)
- springboot+vue项目演示(springboot+VUE实现登录注册)
- php中最常用的标记符(php中目录操作opendir、readdir及scandir用法示例)
- html中table怎么用(详解CSS的table-layout属性的用法)
- mysql中常用的三种存储引擎的区别(MySQL 存储过程的优缺点分析)
- TortoiseSVN客户端更改用户名和密码
- ftp被动模式改成主动模式(如何设置FTP的主动模式和被动模式 FileZilla主动和被动模式设置方法)
- mysql 触发器是什么(MySQL触发器的使用)
- dede织梦如何调用栏目(织梦dedecms rss输出改成全文输出)
- JavaScript生成GUID的方法
排行榜
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9