• python基础之类的内置__setattr__,__delattr__,__getattr__和 二次加工标准类型(包装)


    一、内置attr:__setattr__,__delattr__,__getattr__

    1. __setattr__ #添加/修改属性会触发它的执行
    2. __delattr__ #删除属性的时候会触发
    3. __getattr__ #只有在调用属性且属性不存在的时候才会触发
    class Foo:
        def __init__(self,x):
            self.name=x
    
        def __setattr__(self, key, value):
            # if not isinstance(value,str):
            #     raise TypeError('must be str')
            # print('----setattr---key:%s,value:%s' %(key,value))
            # print(type(key))
            # print(type(value))
            # self.key=value
            # setattr(self,key_str,value) #self.key_attribute=value #这是无限递归
            self.__dict__[key]=value #因为你重写了__setattr__,凡是赋值操作都会触发它的运行,你啥都没写,就是根本没赋值,除非你直接操作属性字典,否则永远无法赋值
    
        def __delattr__(self, item):
            print('delattr:%s' %item)
            print(type(item))
            # delattr(self,item) #这是无限递归
            # del self.item
            self.__dict__.pop(item) #我们可以直接修改属性字典,来完成添加/修改属性的操作
    
    
    f1=Foo('egon') #f1.name='egon'
    
    f1.age=18
    
    print(f1.__dict__)
    print(f1.name)
    print(f1.age)
    
    print(f1.__dict__)
    del f1.age
    print(f1.__dict__)
    print(f1.age)
    
    
    #---------------------getattr------------------------
    
    class Foo:
        def __init__(self,x):
            self.name=x
    
        #属性不存在的情况下才会触发
        def __getattr__(self, item):
            print('getattr-->%s %s' %(item,type(item)))
    
    
    f=Foo('egon')
    # print(f.name)
    
    print(f.xxxxxxx)
    三板斧绝技

     二、二次加工标准类型(包装)

    包装:python默认提供了标准数据类型,以及丰富的内置方法,有时候需要基于标准数据类型来定制我们自己的数据类型,新增或改写方法,这就用到了继承和派生知识(标准类型均可以通过以下方式进行二次加工)

    授权:授权是包装的一个特性, 包装一个类型通常是对已存在的类型的一些定制,这种做法可以新建,修改或删除原有产品的功能。其它的则保持原样。授权的过程,即是所有更新的功能都是由新类的某部分来处理,但已存在的功能就授权给对象的默认属性。

    实现授权的关键点就是覆盖__getattr__方法

    定制自己的数据类型:

    1. 继承的方式
    2. 授权的方式
    l=list([1,2,3])
    
    l.append(4)
    l.append('5')
    print(l)
    
    class List(list):
        pass
    
    l1=List([1,2,3])
    print(l1)
    l1.append(4)
    print(l1)
    l1.append('5')
    print(l1)
    小例子
    #基于继承的原理,来定制自己的数据类型(继承标准类型)
    class List(list):
        def append(self, p_object):
            # print('--->',p_object)
            if not isinstance(p_object,int):
                raise TypeError('must be int')
            # self.append(p_object)
            super().append(p_object)
        def insert(self, index, p_object):
            if not isinstance(p_object,int):
                raise TypeError('must be int')
            # self.append(p_object)
            super().insert(index,p_object)
    #
    l=List([1,2,3])
    # print(l)
    # l.append(4)
    # print(l)
    
    # l.append('5')
    print(l)
    # l.insert(0,-1)
    l.insert(0,'-1123123213')
    print(l)
    
    
    # def test(x:int,y:int)->int:
    #     return x+y
    # print(test.__annotations__)
    #
    # print(test(1,2))
    # print(test(1,'3'))
    #
    # def test(x,y):
    #     return x+y
    基于继承的原理,来定制自己的数据类型(继承标准类型)
    #不能用继承,来实现open函数的功能
    # f=open('a.txt','w')
    # print(f)
    # f.write('1111111')
    
    #授权的方式实现定制自己的数据类型
    import time
    
    
    class Open:
        def __init__(self,filepath,m='r',encode='utf-8'):
            self.x=open(filepath,mode=m,encoding=encode)
    
            self.filepath=filepath
            self.mode=m
            self.encoding=encode
    
        def write(self,line):
            print('f自己的write',line)
            t=time.strftime('%Y-%m-%d %X')
            self.x.write('%s %s' %(t,line))
    
        def __getattr__(self, item):
            # print('=------>',item,type(item))
            return getattr(self.x,item)
    #
    # f=Open('b.txt','w')
    # # print(f)
    # f.write('111111
    ')
    # f.write('111111
    ')
    # f.write('111111
    ')
    
    
    f=Open('b.txt','r+')
    # print(f.write)
    print(f.read)
    
    
    res=f.read() #self.x.read()
    print(res)
    
    print('=-=====>',f.read())
    f.seek(0)
    print(f.read())
    # f.flush()
    # f.close()
    授权的方式实现定制自己的数据类型
    
    
    
  • 相关阅读:
    golang实现单链表
    koa中间执行机制
    vuex源码简析
    从浏览器渲染过程看重绘回流
    javascript的this
    js 设计模式:观察者和发布订阅模式
    H5 移动端 键盘遮挡焦点元素解决方案
    webpack4 css modules
    Daily,一个入门级的 React Native 应用
    javascript: 类型转换
  • 原文地址:https://www.cnblogs.com/luchuangao/p/6758185.html
Copyright © 2020-2023  润新知