python3高级语法:__slots__属性、property装饰器、上下文管理协议、__new__方法
#practice29:派生内置不可变类型并修改其实例化行为(以tuple为例)
__new__() is intended mainly to allow subclasses of immutable types (like int, str, or tuple) to customize instance creation.
__init__()Called after the instance has been created (by __new__()), but before it is returned to the caller.
__new__() and __init__() work together in constructing objects (__new__() to create it, and __init__() to customize it)
- 修改内置不可变类型(int/str/tuple)的实例化行为,做法是:继承内置不可变类,并覆盖其new方法。
- 注意:并非所有内置类都可以简单继承,list/dir/str继承后重新覆盖的某些内置方法会不起作用,即新类还会调用覆盖前的内置方法;为保证不会发生这种情况,最好去继承collections.UserDict/collections.UserList/collections.String
- new负责创建对象,包含创建其大部分内置方法、属性等;init负责个性化定制(初始化)对象,即将init的参数赋值为对象属性!
1、定制化tuple类型
必须重新定义new与init
class IntTuple(tuple):#覆盖tuple的内置静态方法,不需要加装饰器def __new__(cls,iterable):g = (x for x in iterable if isinstance(x,int) and x > 0)return super(IntTuple,cls).__new__(cls,g)#参数iterable必须要有,这是数据入口,随后该数据会被传递给__new__def __init__(self,iterable):print(self)#可选super(IntTuple,self).__init__()a = IntTuple([1,44,'2',(3,5)])#practice30:减小实例内存开销
- 类属性slots用于申明实例的所有属性。
- dict属性用于保存对象的所有属性,并可以动态添加
- 在类属性slots中排除dict属性,即可禁止对象动态添加属性!如:obj.qq = 100,则对象有了新属性qq
1、 定义类属性slots对实例属性的影响
import sys class A():def __init__(self,id,name):self.id = idself.name = nameclass B():__slots__ = ['id','name']def __init__(self,id,name):self.id = idself.name = name print(dir(A(1,'lisi'))) print(dir(B(2,'lisi'))) print(set(dir(A(2,'lisi'))) - set(dir(B(2,'lisi')))) print(sys.getsizeof(A(1,'lisi'))) print(sys.getsizeof(A(1,'lisi').__dict__))属性差异为红色标记的两个属性,weakref对于内存的消耗可不计
practice31:让对象支持上下文管理器
- 实现上下文管理协议主要依赖类的实例方法enter与exit
- 句法 with obj as obj1: pass ,实际执行过程为obj调用enter方法,返回的新对象赋值给obj1,之后执行块内代码,最后obj1执行exit方法!
1、实例
mydict = {}class A():def __init__(self,a,b):self.a = aself.b = bdef __enter__(self):mydict['a'] = self.amydict['b'] = self.b#后三个参数是固定的,异常类型,异常实例、异常traceback对象def __exit__(self,exc_type,exc_val,exc_tb):mydict.clear()print(mydict) with A(3,5) as Q:print(mydict) print(mydict)2、异常捕获与压制
mydict = {}class A():def __init__(self,a,b):self.a = aself.b = bdef __enter__(self):mydict['a'] = self.amydict['b'] = self.b#后三个参数是固定的,异常类型,异常实例、异常traceback对象def __exit__(self,exc_type,exc_val,exc_tb):#对于with代码块中出现的异常,__exit__能捕获print(exc_type,exc_val,exc_tb)mydict.clear()#返回True能成功压制异常!!!return Trueprint(mydict) with A(3,5) as Q:raise Exception('myerror')print(mydict) print(mydict)with代码块产生异常,但任然会执行exit方法,清空字典;这是上下文管理器的默认行为方式,即先执行exit后再抛出代码块内的异常,确保exit方法始终要执行
通过return True成功压制异常,即有异常发生也不抛出!
#practice32:可管理的对象属性
- 直接访问对象属性的形式,如:obj.x = ‘1’,这种方式调用简单,但却不够灵活,例如想要检查属性x的值必须为int,此种方法显然不合适;此外存在安全性问题,如上述赋值后x为str,如果后续进行数学运算,会抛出异常,在程序复杂的情况下很难查找!
使用setx/getx方法来访问属性,相当于中间抽象出一层,进行一些逻辑处理,比较灵活,但每次调用起来比较费劲
解决方法:内置装饰器property
总结
以上是生活随笔为你收集整理的python3高级语法:__slots__属性、property装饰器、上下文管理协议、__new__方法的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: 完美解决Flask-Migrate使用S
- 下一篇: 每天5分钟玩转python3算法:选择排