• Python内部属性


     __setattr__()、__getattr__()、__delattr__() 

    第一次接触这几个方法时,是使用pymongo的时候。pymongo经常会使用['']或"."来获取数据库或集合对象。

    __xxxattr__:使用  '.' 的方式操作属性时被调用

    __setattr__:每当属性被赋值的时候都会调用该方法,因此不能再该方法内赋值 self.name = value 会死循环
    __getattr__:当访问不存在的属性时会调用该方法
    __delattr__:当删除属性时调用该方法

    class A(object):
        def __init__(self):
            self.A = "aa"
            self.C = "CC"
            del self.C 
        
        def __setattr__(self,name,value):
            ''' 
            @summary: 每当属性被赋值的时候都会调用该方法,因此不能再该方法内赋值 self.name = value 会死循环
            '''
            print "__setattr__:Set %s Value %s"%(name,value)
            self.__dict__[name] = value
            
        def __getattr__(self,name):
            ''' 
            @summary: 当访问不存在的属性时会调用该方法
            '''
            print "__getattr__:No attribute named '%s'"%name
            return None
            
        def __delattr__(self,name):
            ''' 
            @summary: 当删除属性时调用该方法
            '''
            print "__delattr__:Delect attribute '%s'"%name
            del self.__dict__[name]
            print self.__dict__
     
    if __name__ == "__main__":
        X = A()
        a = X.aa
    

      

    输出为:

    __setattr__:Set A Value aa
    __setattr__:Set C Value CC
    __delattr__:Delect attribute 'C'
    {'A': 'aa'}
    __getattr__:No attribute named 'aa'
    

      

    Python __setitem__()、__getitem__()、__delitem__()

    __xxxitem__:使用 [''] 的方式操作属性时被调用

    __setitem__:每当属性被赋值的时候都会调用该方法,因此不能再该方法内赋值 self.name = value 会死循环
    __getitem__:当访问不存在的属性时会调用该方法
    __delitem__:当删除属性时调用该方法

    class A(object):
        def __init__(self):
            self['B'] = "BB"
            self['D'] = "DD"
            del self['D']
        
        def __setitem__(self,name,value):
            '''
            @summary: 每当属性被赋值的时候都会调用该方法,因此不能再该方法内赋值 self.name = value 会死循环
            '''
            print "__setitem__:Set %s Value %s"%(name,value)
            self.__dict__[name] = value
        
        def __getitem__(self,name):
            ''' 
            @summary: 当访问不存在的属性时会调用该方法
            '''
            print "__getitem__:No attribute named '%s'"%name
            return None
        
        def __delitem__(self,name):
            ''' 
            @summary: 当删除属性时调用该方法
            '''
            print "__delitem__:Delect attribute '%s'"%name
            del self.__dict__[name]
            print self.__dict__
        
        
    if __name__ == "__main__":
        X = A()
        b = X['bb']
    

      输出:

    __setitem__:Set B Value BB
    __setitem__:Set D Value DD
    __delitem__:Delect attribute 'D'
    {'B': 'BB'}
    __getitem__:No attribute named 'bb'
    

      

    Python __len__()、__reversed__()、__contains__()

    __len__():当使用len(A)该对象时调用该方法,当没有该方法是会报错,且返回数据不为整数也会报错

    class A(object):
        def __init__(self,num):
            self.num = num
            self.start_num = -1
        
        def __len__(self):
            '''
            @summary: 当使用len(Test)该对象时调用该方法,当没有该方法是会报错,且返回数据不为整数也会报错
            '''
            print "__len__"
            return self.num - self.start_num - 1
        
    if __name__ == "__main__":
        print len(A(10))

    输出:

    __len__
    10
    

     

    __reversed__():当使用reversed函数翻转对象时调用

    class A(object):
        def __init__(self,num):
            self.num = num
        
        def __reversed__(self):
            '''
            @summary: 当使用reversed函数翻转对象时调用
            '''
            ret = []
            for i in range(self.num):
                ret.append(self.num - i-1)
            return ret
        
    if __name__ == "__main__":
        print reversed(A(10)) 

    输出:

    [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
    

    __contains__():当使用in,not in 对象的时候 调用(not in 是在in完成后再取反,实际上还是in操作)

    class A(object):
        def __init__(self,num):
            self.num = num
        
        def __contains__(self, item):
            '''
            @summary:当使用in,not in 对象的时候 ,not in 是在in完成后再取反,实际上还是in操作
            '''
            print "__contains__:%s is in?"%item
            if item < self.num and item >= 0:
                return True
            return False
        
    if __name__ == "__main__":
        if 3 in A(10):print "True"
        else:print False
        if 3 not in A(10):print "True"
        else:print False
    

      输出:

    __contains__:3 is in?
    True
    __contains__:3 is in?
    False
    

      

    __iter__():迭代器,生成迭代对象时调用,返回值必须是对象自己,然后for可以循环调用next方法

    next():每一次for循环都调用该方法(必须存在)

    class A(object):
        def __init__(self,num):
            self.num = num
            self.start_num = -1
        
        def __iter__(self):
            '''
            @summary: 迭代器,生成迭代对象时调用,返回值必须是对象自己,然后for可以循环调用next方法
            '''
            print "__iter__"
            return self
        
        def next(self):
            '''
            @summary: 每一次for循环都调用该方法(必须存在)
            '''
            self.start_num += 1
            if self.start_num >= self.num:
                raise StopIteration()
            return self.start_num
        
    if __name__ == "__main__":
        for i in A(10):print i,  

    输出:

     __iter__
     
    0 1 2 3 4 5 6 7 8 9
     
    

      

    python 中__getitem__ 和 __iter__ 的区别

    # -*- coding: utf-8 -*-
    
    class Library(object):
        def __init__(self):                                                     
            self.books = { 'title' : 'a', 'title2' : 'b', 'title3' : 'c', }
            
        def __getitem__(self, i):
            return self.books[i]
            
        def __iter__(self):
            # 方法1 使用生成器
            for titles in self.books:
                yield self.books[titles]
            # 方法2 使用迭代器
    #        return self.books.itervalues()
     
    library = Library()
    
    # 1.普通方法
    print library.books['title']
    
    # 2.使用__getitem__
    print library['title']
    
    # 3.迭代器
    for book in library:
        print book
    

      

    问题:那__getitem__可以替代__iter__方法吗?

    1、list

    # -*- coding: utf-8 -*-
    
    class Library(object):
        def __init__(self):                                                     
            self.books = [ 'title' , 'a', 'title2' , 'b', 'title3' , 'c', ]
            
        def __getitem__(self, i):
            return self.books[i]
            
     #   def __iter__(self):
            # 方法1 使用生成器
      #      for titles in self.books:
      #          yield self.books[titles]
            # 方法2 使用迭代器
    #        return self.books.itervalues()
     
    library = Library()
    
    # 1.普通方法
    print(library.books[1])
    
    # 2.使用__getitem__
    print(library[1])
    
    # 3.迭代器
    for book in library:
        print(book)

    结果为:

    a
    a
    title
    a
    title2
    b
    title3
    c
    

      

    2、dict

    # -*- coding: utf-8 -*-
    
    class Library(object):
        def __init__(self):                                                     
            self.books = { 'title' : 'a', 'title2' : 'b', 'title3' : 'c', }
            
        def __getitem__(self, i):
            return self.books[i]
            
     #   def __iter__(self):
            # 方法1 使用生成器
      #      for titles in self.books:
      #          yield self.books[titles]
            # 方法2 使用迭代器
    #        return self.books.itervalues()
     
    library = Library()
    
    # 1.普通方法
    print(library.books[1])
    
    # 2.使用__getitem__
    print(library[1])
    
    # 3.迭代器
    for book in library:
        print(book)
    

     结果为:

    Traceback (most recent call last):
      File "C:/Users/CUI/Desktop/1.py", line 20, in <module>
        print(library.books[1])
    KeyError: 1
    

      结论:当字段为索引行数据类型(如:list, tuple,str)时,可以替换,当字段为hash型类型(如dict,set)时,不能替换。

    Python __call__()

    __call__() :__call__() 方法可以让类像方法一样被调用

    class Call(object):
        def __init__(self):
            pass
        
        def __call__(self,ret):
            '''
            @summary: 将类对象当做方法直接使用时,调用该方法
            '''
            print "__call__:Negate ",ret
            ret = - ret
            return ret
        
    if __name__ == "__main__":
        A = Call()
        print A(15)
    

      输出为:

    __call__:Negate  15
    -15
    

      

    Python __enter__()、__exit__()

    __enter__():在使用with语句时调用,会话管理器在代码块开始前调用,返回值与as后的参数绑定

    __exit__():会话管理器在代码块执行完成好后调用,在with语句完成时,对象销毁之前调用

    test.txt:

     
    
    Hello world!
    

      

    class Test(object):
        def __init__(self,name,flag):
            self.filename = name
            self.flag = flag
        
        def __enter__(self):
            '''
            @summary: 使用with语句是调用,会话管理器在代码块开始前调用,返回值与as后的参数绑定
            '''
            print "__enter__:Open %s"%self.filename
            self.f = open(self.filename,self.flag)
            return self.f
            
        def __exit__(self,Type, value, traceback):
            '''
            @summary: 会话管理器在代码块执行完成好后调用(不同于__del__)(必须是4个参数)
            '''
            print "__exit__:Close %s"%self.filename
            self.f.close()
            
        def __del__(self):
            print "__del__"
            
    if __name__ == "__main__":
        with Test('test.txt','r+') as f:
            content = f.read()
            print content
        print "end"
    

      输出:

    __enter__:Open test.txt
    Hello world!
    __exit__:Close test.txt
    del
    end
    

      

    综合:

    1、

    __setattr__、__getattr__、__delattr__、__setitem__、__getitem__、__delitem__

    #coding=utf-8
    '''
    Created on 2015-8-27
    @author: xhw
    @explain: 属性相关
    '''
    '''使用super可以调用父类的方法,或重写前的内置方法'''
     
    class Test(object):
        def __init__(self):
            self.A = "aa"
            self['B'] = "BB"
            self.C = "CC"
            self['D'] = "DD"
            del self.C
            del self['D']
            
        "------------------------------------------------------------------------------"
        "----------------------attr:使用  '.' 的方式操作属性时被调用-----------------------"
        "------------------------------------------------------------------------------"   
        
        def __setattr__(self,name,value):
            ''' 
            @summary: 每当属性被赋值的时候都会调用该方法,因此不能再该方法内赋值 self.name = value 会死循环
            '''
            print "__setattr__:Set %s Value %s"%(name,value)
            self.__dict__[name] = value
            
        def __getattr__(self,name):
            ''' 
            @summary: 当访问不存在的属性时会调用该方法
            '''
            print "__getattr__:No attribute named '%s'"%name
            return None
            
        def __delattr__(self,name):
            ''' 
            @summary: 当删除属性时调用该方法
            '''
            print "__delattr__:Delect attribute '%s'"%name
            del self.__dict__[name]
            print self.__dict__
            
        "------------------------------------------------------------------------------"
        "--------------------item:使用 [''] 的方式操作属性时被调用-------------------------"
        "------------------------------------------------------------------------------"
        
        def __setitem__(self,name,value):
            '''
            @summary: 每当属性被赋值的时候都会调用该方法,因此不能再该方法内赋值 self.name = value 会死循环
            '''
            print "__setitem__:Set %s Value %s"%(name,value)
            self.__dict__[name] = value
        
        def __getitem__(self,name):
            ''' 
            @summary: 当访问不存在的属性时会调用该方法
            '''
            print "__getitem__:No attribute named '%s'"%name
            return None
        
        def __delitem__(self,name):
            ''' 
            @summary: 当删除属性时调用该方法
            '''
            print "__delitem__:Delect attribute '%s'"%name
            del self.__dict__[name]
            print self.__dict__
        
        
        
    if __name__ == "__main__":
        A = Test()
        a = A.aa
        b = A['bb']
        
    

    2、__len__、__iter__、__reversed__、__contains__、__concat__

    #coding=utf-8
    '''
    Created on 2015-8-27
    @author: xhw
    @explain: pass
    '''
    class Test(object):
        def __init__(self,num):
            self.num = num
            self.start_num = -1
        
        def __len__(self):
            '''
            @summary: 当使用len(Test)该对象时调用该方法,当没有该方法是会报错,且返回数据不为整数也会报错
            '''
            print "__len__"
            return self.num - self.start_num - 1
        
        def __iter__(self):
            '''
            @summary: 迭代器,生成迭代对象时调用,返回值必须是对象自己,然后for可以循环调用next方法
            '''
            print "__iter__"
            return self
        
        def next(self):
            '''
            @summary: for循环时调用该方法
            '''
            self.start_num += 1
            if self.start_num >= self.num:
                raise StopIteration()
            return self.start_num
        
        def __reversed__(self):
            '''
            @summary: 当使用reversed函数翻转对象时调用
            '''
            ret = []
            for i in range(self.num - 1):
                ret.append(self.num - i)
            return ret
        
        def __contains__(self, item):
            '''
            @summary:当使用in,not in 对象的时候 ,not in 是在in完成后再取反,实际上还是in操作
            '''
            print "__contains__:%s is in?"%item
            if item < self.num and item >= 0:
                return True
            return False
        
        def __concat__(self,other):
            '''
            @summary: 据说是在使用‘+’操作符操作对象时调用,但不知道该怎么调用(貌似string 和 list内置该方法)
            '''
            print "__concat__:Concat ",other
            ret = []
            for i in range(self.num - 1):
                ret.append(self.num - i)
            return ret.extend(other)
            
            
        
        
    if __name__ == "__main__":
        print len(Test(10))
         
        for i in Test(10):print i
         
        print reversed(Test(10))
         
        if 3 in Test(10):print "True"
        else:print False
        if 3 not in Test(10):print "True"
        else:print False
        
    

    3、 __call__、with、__enter__、__exit__

    #coding=utf-8
    '''
    Created on 2015-8-28
    @author: xhw
    @explain: pass
    '''
    class Call(object):
        def __init__(self):
            pass
        
        def __call__(self,ret):
            '''
            @summary: 将类对象当做方法直接使用时,调用该方法
            '''
            print "__call__:Negate ",ret
            ret = - ret
            
    class Test(object):
        def __init__(self,name,flag):
            self.filename = name
            self.flag = flag
        
        def __enter__(self):
            '''
            @summary: 使用with语句是调用,会话管理器在代码块开始前调用,返回值与as后的参数绑定
            '''
            print "__enter__:Open %s"%self.filename
            self.f = open(self.filename,self.flag)
            return self.f
            
        def __exit__(self,Type, value, traceback):
            '''
            @summary: 会话管理器在代码块执行完成好后调用(不同于__del__)(必须是4个参数)
            '''
            print "__exit__:Close %s"%self.filename
            self.f.close()
            
    if __name__ == "__main__":
        A = Call()
        print A(15)
            
        with Test('test.txt','r+') as f:
            content = f.read()
            print content
        
    

      

  • 相关阅读:
    网鼎杯_2018 _Web_fakebook
    CISCN 2019-ikun
    流浪者-CTF
    wtf.sh-150
    bug-ctf
    EasyRE
    MySQL 存储引擎特性和线程模型
    InnoDB体系结构---物理存储结构
    mysql数据页结构及行格式
    linux系统清理缓存
  • 原文地址:https://www.cnblogs.com/noticeable/p/14693545.html
Copyright © 2020-2023  润新知