zoukankan      html  css  js  c++  java
  • 组合的方式完成授权

    1、包装是在之前原有的方法的基础上,在做一点改动,这叫包装,就像包装那个append方法

    现在我们来做一个open方法

    class Open:
        def __init__(self,filename,mode="r",encoding="utf8"):
            self.filename=filename
            self.mode=mode
            self.encoding=encoding
        def __getattr__(self, item):
            print(item)
    f1=Open("a.txt","r")
    f1.read
    
    C:python35python3.exe D:/pyproject/day26/授权.py
    
    read

    2、啥都没做,那我们来改动一下

    现在就创建了一个a.txt

    class Open:
        def __init__(self,filename,mode="r",encoding="utf8"):
            # self.filename=filename
            self.file=open(filename,mode,encoding=encoding)#得到的是一个文件句柄
            self.mode=mode
            self.encoding=encoding
        def __getattr__(self, item):#当实例调用的属性不存在的时候触发它
            print(item)
    f1=Open("a.txt","w")#f1传给self a.txt传给filename w 传给mode
    print(f1.file)
    f1.read#此时read并不存在,所以触发了__getattr__
    
    C:python35python3.exe D:/pyproject/day26/授权.py
    
    <_io.TextIOWrapper name='a.txt' mode='w' encoding='utf8'>
    
    read

    3、再改善一下

    class Open:
        def __init__(self,filename,mode="r",encoding="utf8"):
            # self.filename=filename
            self.file=open(filename,mode,encoding=encoding)#得到的是一个文件句柄
    #self.file里面调用了系统的open方法,封装成了自己的open方法,具有系统的open方法的所有特性
            self.mode=mode
            self.encoding=encoding
        def __getattr__(self, item):#当实例调用的属性不存在的时候触发它
            return getattr(self.file,item)#self.file-->f1.file   item-->"read"
    f1=Open("a.txt","w")#f1传给self a.txt传给filename w 传给mode
    print(f1.file)
    print(f1.read)#此时read并不存在
    
    C:python35python3.exe D:/pyproject/day26/授权.py
    
    <_io.TextIOWrapper name='a.txt' mode='w' encoding='utf8'>
    
    <built-in method read of _io.TextIOWrapper object at 0x000000000057EA68>

    4、我们看下我们自己的这个read跟系统的open方法的read是不是一个东西

    class Open:
        def __init__(self,filename,mode="r",encoding="utf8"):
            # self.filename=filename
            self.file=open(filename,mode,encoding=encoding)#得到的是一个文件句柄
    #self.file里面调用了系统的open方法,封装成了自己的open方法,具有系统的open方法的所有特性
            self.mode=mode
            self.encoding=encoding
        def __getattr__(self, item):#当实例调用的属性不存在的时候触发它
            return getattr(self.file,item)#self.file-->f1.file   item-->"read"
    f1=Open("a.txt","w")#f1传给self a.txt传给filename w 传给mode
    print(f1.file)
    print(f1.read)#获取我们的实例的自己写的read方法,但是实例里面没有,类里面也没有,最终触发了getattr
    sys_f=open("b.txt","w+")
    print(getattr(sys_f,"read"))#获取系统的open的read方法
    
    C:python35python3.exe D:/pyproject/day26/授权.py
    
    <_io.TextIOWrapper name='a.txt' mode='w' encoding='utf8'>
    
    <built-in method read of _io.TextIOWrapper object at 0x000000000055EA68>
    
    <built-in method read of _io.TextIOWrapper object at 0x000000000055EB40>

    5、现在f.write也能调用了。read你会调用了write也是一样的呀,实例里面没有,类里面也没有,最终触发了getattr,getattr里面是调用的系统的open方法里面的write。所以肯定是可以的

    class FileHandle:
        def __init__(self,filename,mode="r",encoding="utf8"):
            # self.filename=filename
            self.file=open(filename,mode,encoding=encoding)#得到的是一个文件句柄
    #self.file里面调用了系统的open方法,封装成了自己的open方法,具有系统的open方法的所有特性
            self.mode=mode
            self.encoding=encoding
        def __getattr__(self, item):#当实例调用的属性不存在的时候触发它
            return getattr(self.file,item)#self.file-->f1.file   item-->"read"
    f1=FileHandle("a.txt","r+")#f1传给self a.txt传给filename w 传给mode
    print(f1.read)#获取我们实例自己写的read方法,但是实例里面没有,类里面也没有,最终触发了getattr
    
    print(f1.write)
    
    C:python35python3.exe D:/pyproject/day26/授权.py
    
    <built-in method read of _io.TextIOWrapper object at 0x00000000005AEA68>
    
    <built-in method write of _io.TextIOWrapper object at 0x00000000005AEA68>

    6、我们执行一下write操作看看能不能写入到文件里面

    结果是a.txt里面成功写入了,现在就牛逼了。我们发现我们的实例f1是通过FileHandle这个方法进行write的,并不是系统的open的方法里面的write属性,是经过了getattr中转了一下。

    class FileHandle:
        def __init__(self,filename,mode="r",encoding="utf8"):
            # self.filename=filename
            self.file=open(filename,mode,encoding=encoding)#得到的是一个文件句柄
    #self.file里面调用了系统的open方法,封装成了自己的open方法,具有系统的open方法的所有特性
            self.mode=mode
            self.encoding=encoding
        def __getattr__(self, item):#当实例调用的属性不存在的时候触发它
            return getattr(self.file,item)#self.file-->f1.file   item-->"read"
    f1=FileHandle("a.txt","r+")#f1传给self a.txt传给filename w 传给mode
    print(f1.read)#获取我们实例自己写的read方法,但是实例里面没有,类里面也没有,最终触发了getattr
    
    f1.write("1111111
    "

    7、我们seek一下,再读一下,到这一步,我们发现,相当于open的所有的方法都传递过来了,都可以正常使用了,上一个是学的包装,继承和派生完成的包装,继承是父类由什么我就继承过来,现在到这里就相当于把open里面的方法继承过来了

    class FileHandle:
        def __init__(self,filename,mode="r",encoding="utf8"):
            # self.filename=filename
            self.file=open(filename,mode,encoding=encoding)#得到的是一个文件句柄
    #self.file里面调用了系统的open方法,封装成了自己的open方法,具有系统的open方法的所有特性
            self.mode=mode
            self.encoding=encoding
        def __getattr__(self, item):#当实例调用的属性不存在的时候触发它
            return getattr(self.file,item)#self.file-->f1.file   item-->"read"
    f1=FileHandle("a.txt","r+")#f1传给self a.txt传给filename w 传给mode
    f1.write("123456
    ")
    f1.seek(1)
    print(f1.read())
    
    C:python35python3.exe D:/pyproject/day26/授权.py
    
    23456

    8、上面完成了读操作了,还没有完成写操作呢

    实例再调用wirte的方法的时候,先在实例的属性字典里面找,然后去类的属性字典里面找,找不到的话才会触发getattr,所以我们想完成写操作,就在类里面定义一个write的方法就行了,当实例调用的时候会先从类里面找到write就直接执行了

    class FileHandle:
        def __init__(self,filename,mode="r",encoding="utf8"):
            # self.filename=filename
            self.file=open(filename,mode,encoding=encoding)#得到的是一个文件句柄
    #self.file里面调用了系统的open方法,封装成了自己的open方法,具有系统的open方法的所有特性
            self.mode=mode
            self.encoding=encoding
        def write(self,line):
            print("自己的类里面的定义的write",line)
        def __getattr__(self, item):#当实例调用的属性不存在的时候触发它
            return getattr(self.file,item)#self.file-->f1.file   item-->"read"
    f1=FileHandle("a.txt","w+")#f1传给self a.txt传给filename w 传给mode
    f1.write("123456
    ")
    f1.seek(1)
    print(f1.read())
    
    C:python35python3.exe D:/pyproject/day26/授权.py
    
    自己的类里面的定义的write 123456

    现在这个write就是调用的自己在类里面定义的那个write方法了,并没有真实的写入到文件中去,而且单纯的打印了一下东西

    9、如何实现文件的真正的写操作呢

    class FileHandle:
        def __init__(self,filename,mode="r",encoding="utf8"):
            # self.filename=filename
            self.file=open(filename,mode,encoding=encoding)#得到的是一个文件句柄
    #self.file里面调用了系统的open方法,封装成了自己的open方法,具有系统的open方法的所有特性
            self.mode=mode
            self.encoding=encoding
        def write(self,line):
            # print("自己的类里面的定义的write",line)
            self.file.write(line)
        def __getattr__(self, item):#当实例调用的属性不存在的时候触发它
            return getattr(self.file,item)#self.file-->f1.file   item-->"read"
    f1=FileHandle("a.txt","w+")#f1传给self a.txt传给filename w 传给mode
    f1.write("123456
    ")#把f1传给self,把123456传给line
    f1.seek(1)
    print(f1.read())
    
    C:python35python3.exe D:/pyproject/day26/授权.py
    
    23456

    10、给文件内容的前面每行都加上时间

    import time
    class FileHandle:
        def __init__(self,filename,mode="r",encoding="utf8"):
            # self.filename=filename
            self.file=open(filename,mode,encoding=encoding)#得到的是一个文件句柄
    #self.file里面调用了系统的open方法,封装成了自己的open方法,具有系统的open方法的所有特性
            self.mode=mode
            self.encoding=encoding
        def write(self,line):
            # print("自己的类里面的定义的write",line)
            t=time.strftime("%Y-%m-%d %X")#定义时间格式
            self.file.write("%s %s" %(t,line))#进行字符串拼接
        def __getattr__(self, item):#当实例调用的属性不存在的时候触发它
            return getattr(self.file,item)#self.file-->f1.file   item-->"read"
    f1=FileHandle("a.txt","w+")#f1传给self a.txt传给filename w 传给mode
    f1.write("123456
    ")#把f1传给self,把123456传给line
    f1.write("234567
    ")
    f1.write("789123
    ")
    
    2018-06-20 22:37:13 123456
    2018-06-20 22:37:13 234567
    2018-06-20 22:37:13 789123

    这种就是组合的方式,给self.file赋予了一个文件描述符,然后利用__getattr__来return所有正常的open里面的所有的属性,如果我们不自己定制write的方法的话,所有的方法就已经是跟系统的方法一样了,但是我们自己定制了write的方法了,给前面加了时间,当然也可以做其他的,比如直接pass,那其他人在调用write的方法的时候就写入不了了

  • 相关阅读:
    cocos2d-x simpleGame 0
    cocos2d-x 下的HelloWorld
    cocos2d-x windows 配置
    算术入门之加减乘除
    计算摄氏温度
    输出倒三角图案
    厘米换算英尺英寸
    多文件模块的学生信息库系统
    GPS数据处理
    单词长度
  • 原文地址:https://www.cnblogs.com/gouguoqilinux/p/9215568.html
Copyright © 2011-2022 走看看