Python基础第21天
发布日期:2022-03-13 05:36:14 浏览次数:12 分类:技术文章

本文共 3997 字,大约阅读时间需要 13 分钟。

一:描述符

      1、描述符是什么:描述符本质就是一个新式类,在这个新式类中,至少实现了__get__(),__set__(),__delete__()中的一个,这也被称为描述符协议

__get__():调用一个属性时,触发
__set__():为一个属性赋值时,触发
__delete__():采用del删除属性时,触发

      2、 描述符是干什么的:描述符的作用是用来代理另外一个类的属性的(必须把描述符定义成这个类的类属性,不能定义到构造函数中)

class Foo:    def __get__(self, instance, owner):        print('get方法')    def __set__(self, instance, value):        print('set方法')        instance.__dict__['x']=value  #b1.__dict__    def __delete__(self, instance):        print('delete方法')

何时何地用 :

   描述符应该在另外一个类的类属性定义,请看例子

class Foo:    def __get__(self, instance, owner):        print('get方法')    def __set__(self, instance, value):        print('set方法')        # instance.__dict__['x']=value  #b1.__dict__    def __delete__(self, instance):        print('delete方法')# f1=Foo()# f1.name='egon'#自己不会触发#class Bar:    x=Foo()   #在何地    这就是描述符,x被Foo描述    def __init__(self,x):        self.x=xprint(Bar.__dict__)#在何时b1=Bar(10)b1.xb1.x=1del b1.xprint(b1.__dict__) #所以是空

描述符分类:

  • 数据描述符   __get__()  __set__()
  • 非数据描述符  :没有实现__set__()

描述符优先级高低分别是:

1.类属性

2.数据描述符
3.实例属性
4.非数据描述符
5.找不到的属性触发__getattr__()

class Foo:    def __get__(self, instance, owner):        print('get方法')    def __set__(self, instance, value):        print('set方法')        instance.__dict__['x']=value  #b1.__dict__    def __delete__(self, instance):        print('delete方法')class Bar:    x=Foo()print(Bar.x)  #get方法没有返回值Bar.x=1print(Bar.__dict__)print(Bar.x)  #不会触发get方法,所以类属性比数据描述符有更高优先级print(Bar.__dict__)b1=Bar()   #实例化b1.x #getb1.x=1  #setdel b1.x  #delete   说明数据描述符比实例属性有更高的优先级#b1=Bar()Bar.x=11111111111111111b1.x  #不会触发
1/2/3之间的优先级级比较
class Foo:    def __get__(self, instance, owner):        print('get方法')    # def __delete__(self, instance):    #     print('delete方法')class Bar:    x=Foo()b1=Bar()b1.x=1print(b1.__dict__)  #{'x': 1}  说明实例属性比非数据描述符优先级高
实例属性>非数据描述符
class Foo:    def __get__(self, instance, owner):        print('get方法')    # def __delete__(self, instance):    #     print('delete方法')class Bar:    x=Foo()b1=Bar()b1.x=1print(b1.__dict__)  #{'x': 1}  说明实例属性比非数据描述符优先级高class Foo:    def __set__(self, instance, value):        print('set')    def __get__(self, instance, owner):        print('get')class Room:    name=Foo()    def __init__(self,name,width,length):        self.name=name        self.width=width        self.length=length#name是一个数据描述符,因为name=Foo()而Foo实现了get和set方法,因而比实例属性有更高的优先级#对实例的属性操作,触发的都是描述符的r1=Room('厕所',1,1)r1.name='厨房'print(r1.name)   #Noneclass Foo:    def __get__(self, instance, owner):        print('get')class Room:    name=Foo()    def __init__(self,name,width,length):        self.name=name        self.width=width        self.length=length#name是一个非数据描述符,因为name=Foo()而Foo没有实现set方法,因而比实例属性有更低的优先级#对实例的属性操作,触发的都是实例自己的r1=Room('厕所',1,1)r1.name='厨房'print(r1.name)   #厨房
数据描述符>实例属性>非数据描述符

二:__enter__  和__exit__

操作文件对象的时候可以这么写:

with open(a.txt) as f:

     '代码块'

上述叫做上下文管理协议,即with语句,为了让一个对象兼容with语句,必须在这个对象的类中声明__enter__和__exit__方法

class Open:    def __init__(self,name):        self.name=name    def __enter__(self):        print('出现with语句,对象的__enter__被触发,有返回值则赋值给as声明的变量')        # return self    def __exit__(self, exc_type, exc_val, exc_tb):        print('with中代码块执行完毕时执行我啊')with Open('a.txt') as f:    print('=====>执行代码块')    # print(f,f.name)上下文管理协议:enter会在with执行后触发,而exit会在with里面代码块执行完毕触发。

总结:

优点:

1.使用with语句的目的就是把代码块放入with中执行,with结束后,自动完成清理工作,无须手动干预

2.在需要管理一些资源比如文件,网络连接和锁的编程环境中,可以在__exit__中定制自动释放资源的机制,你无须再去关系这个问题,这将大有用处

class Open:    def __init__(self,name):        self.name=name    def __enter__(self):        print('执行enter')        return self    def __exit__(self, exc_type, exc_val, exc_tb):        print('执行exit')        print(exc_type)        print(exc_val)  #异常的值        print(exc_tb)   #追踪异常的类 traceback        return True   # with语句执行完 因为返回True,结束with后接着往下走with Open('a.txt') as f:  #触发enter ,其返回值self给f  结束后会触发exit   f=obj.__enter__()    print('=====>')    print(f)    print(asdfghjkl)  #没有直接报错,一旦有异常直接跳到exit    print('---------------')print('0000000000000000')

 

转载于:https://www.cnblogs.com/xyd134/p/6561978.html

转载地址:https://blog.csdn.net/weixin_30323961/article/details/98242483 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:AUTEL MaxiSYS Pro MS908P Diagnostic System with WiFi Update Online
下一篇:sql语句

发表评论

最新留言

路过按个爪印,很不错,赞一个!
[***.219.124.196]2024年04月07日 01时24分55秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章