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的方法的时候就写入不了了

  • 相关阅读:
    86. Partition List
    328. Odd Even Linked List
    19. Remove Nth Node From End of List(移除倒数第N的结点, 快慢指针)
    24. Swap Nodes in Pairs
    2. Add Two Numbers(2个链表相加)
    92. Reverse Linked List II(链表部分反转)
    109. Convert Sorted List to Binary Search Tree
    138. Copy List with Random Pointer
    为Unity的新版ugui的Prefab生成预览图
    ArcEngine生成矩形缓冲区
  • 原文地址:https://www.cnblogs.com/gouguoqilinux/p/9215568.html
Copyright © 2011-2022 走看看