• python双下方法__汇总


    1. getattr
    class ObjectDict(dict):
        def __init__(self, *args, **kwargs):
            super(ObjectDict, self).__init__(*args, **kwargs)
    
        def __getattr__(self, name):
            value = self[name]    # 这种使用没见过
            if isinstance(value, dict):
                value = ObjectDict(value)
            return value
    
    
    od = ObjectDict(asf={'a': 1}, d=True)
    print(od.d)                 # True,不实现__getattr__,报错 'ObjectDict' object has no attribute 'd'
    print(od['d'])              # True,不实现__getattr__也可以使用
    
    # 注意
    如果有属性self.name,使用od.name的时候不会触发__getattr__ ,只有‘点’不存在属性,才会触发这个方法
    
    
    1. getstate , setstate 【pickle相关】
    
    class Foo(object):
      def __init__(self, val=2):
         self.val = val
    
      def __getstate__(self):
         print("I'm being pickled")
         self.val *= 2
         return self.__dict__
    
      def __setstate__(self, d):
         print("I'm being unpickled with these values: " + repr(d))
    
         self.__dict__ = d
         self.val *= 3
    
    import pickle
    
    f = Foo()
    f_data = pickle.dumps(f)
    f_new = pickle.loads(f_data)
    print(f_new.val)
    
    
    1. getiterm/setiterm/deliterm 【[] 运算相关】
    class Person(object):
        def __init__(self, name):
            self.name = name
    
        def __getitem__(self, item):
            return self.__dict__[item]
    
        def __setitem__(self, key, value):
            self.__dict__[key] = value
    
        def __delitem__(self, key):
            del self.__dict__[key]
    
    obj = Person("pd")
    
    ret = obj["name"]     # 自动执行 __getitem__ 方法
    print(ret)            # pd
    obj["name"] = "佩奇"  # 自动执行 __setitem__ 方法
    print(obj["name"])    # 佩奇
    del obj["name"]       # 自动执行 __delitem__ 方法
    # print(obj["name"])  # 报错,KeyError: 'name'
    
    1. new/init 【元编程,单例模式等】
    https://www.cnblogs.com/amize/p/14599983.html
    https://www.cnblogs.com/amize/p/14684780.html
    
    1. dict
    class Animal(object):
        run = True
    class Dog(Animal):
        fly = False
        def __init__(self, age):
            self.age = age
        def sound(self):
            return "wang wang~"
    
    dog = Dog(1)
    # 查看dog对象的属性
    print ('dog.__dict__:',dog.__dict__)
    # 查看类Dog的属性
    print ('Dog.__dict__:',Dog.__dict__)
    # 查看类Animal的属性
    print ('Animal.__dict__:',Animal.__dict__)
    
    #结果 (和dir区别)
    #属性在哪个对象上定义,便会出现在哪个对象的__dict__中
    '''
    dog.__dict__:    {'age': 1}
    Dog.__dict__:    {'__module__': '__main__', 'fly': False, '__init__': <function Dog.__init__ at 0x0000024C426BAB88>, 'sound': <function Dog.sound at 0x0000024C426BA948>, '__doc__': None}
    Animal.__dict__: {'__module__': '__main__', 'run': True, '__dict__': <attribute '__dict__' of 'Animal' objects>, '__weakref__': <attribute '__weakref__' of 'Animal' objects>, '__doc__': None}
    '''
    
    
    1. str/repr
    
    # 相同的例子
    class Test:
        pass
    
    print(str(Test()))
    print(repr(Test()))
    print(str(Test()) == repr(Test()))
    
    #输出结果: 
    '''
    <class '__main__.Test'>
    <class '__main__.Test'>
    True  # 默认情况下一样
    '''
    
    
    # 区别
    1. _str_  用于为最终用户创建输出,而 _repr_ 主要用于调试和开发。 _repr_ 的目标是明确无误,_str_ 是可读的
    2. _repr_ 用于推断对象的"官方"字符串表示形式(包含有关对象的所有信息的表示), _str_ 用于推断对象的“非正式”字符串表示形式(对打印对象有用的表示形式)
    
    #再通过一个例子说明问题:
    import datetime
    today = datetime.datetime.now()
    
    print str(today)
    print repr(today)
    
    # 输出结果如下:
    '''
    2018-08-22 16:52:37.403320
    datetime.datetime(2018, 8, 22, 16, 52, 37, 403320)
    '''
    
    
    1. name/qualname
    
    
    1. 进阶
    • add/sub
    
    
    • _import_
    
    
    • _mro_/slot/
    
    

    get(),set(),delete()

    https://www.cnblogs.com/andy1031/p/10923834.html

    拥有这个方法的类,应该(也可以说是必须)产生一个实例,并且这个实例是另外一个类的类属性(注意一定是类属性,通过self的方式产生就不属于__get__范畴了)。
    也就是说拥有这个方法的类,那么它的实例应该属于另外一个类/对象的一个属性。

    非资料描述器,也就是只有__get__,不管是类还是实例去访问,默认都获得的是__get__的返回值,但是,如果中间有任何一次重新赋值,那么,这个实例获得的是新的值(对象),已经和原来的描述器完全脱离了关系
    资料描述器,比如有__set__方法,后期通过实例对描述器进行赋值,那么访问的是__set__,并且永远关联起来。但是如果通过修改类属性的方式复制,那么也会被重新获取新的值(对象)。

    # __get__ 的使用
    class TestDes:
        def __get__(self, instance, owner):
            print(instance, owner)
            return 'TestDes:__get__'
    
    
    class TestMain:
        des = TestDes()
    
    
    if __name__ == '__main__':
        t = TestMain()
        print(t.des)
        print(TestMain.des)
    
    
    # __get__ __set__ 的使用
    class TestDes:
        def __get__(self, instance, owner):
            print('TestDes:__get__:', instance, owner)
            return 'TestDes:__get__return'
    
        def __set__(self, instance, value):
            print('TestDes:__set__:', instance, value)
    
    
    class TestMain:
        des = TestDes()
    
    
    if __name__ == '__main__':
        t = TestMain()
        print(t.des)
        print(TestMain.des)
    
        print('*************************')
    
        t.des = 1
        print(t.des)
        print(TestMain.des)
    
        print('*************************')
    
        TestMain.des = 1
        print(t.des)
        print(TestMain.des)
    
    '''
    TestDes:__get__: <__main__.TestMain object at 0x06C04C70> <class '__main__.TestMain'>
    TestDes:__get__return
    TestDes:__get__: None <class '__main__.TestMain'>
    TestDes:__get__return
    *************************
    TestDes:__set__: <__main__.TestMain object at 0x06C04C70> 1
    TestDes:__get__: <__main__.TestMain object at 0x06C04C70> <class '__main__.TestMain'>
    TestDes:__get__return
    TestDes:__get__: None <class '__main__.TestMain'>
    TestDes:__get__return
    *************************
    1
    1
    '''
    
    
    
    #描述符Str
    class Str:
        def __get__(self, instance, owner):
            print('Str调用')
        def __set__(self, instance, value):
            print('Str设置...')
        def __delete__(self, instance):
            print('Str删除...')
    
    #描述符Int
    class Int:
        def __get__(self, instance, owner):
            print('Int调用')
        def __set__(self, instance, value):
            print('Int设置...')
        def __delete__(self, instance):
            print('Int删除...')
    
    class People:
        name=Str()
        age=Int()
        def __init__(self,name,age): #name被Str类代理,age被Int类代理,
            self.name=name
            self.age=age
    
    #何地?:定义成另外一个类的类属性
    
    #何时?:且看下列演示
    
    p1=People('alex',18)
    
    #描述符Str的使用
    p1.name
    p1.name='egon'
    del p1.name
    
    #描述符Int的使用
    p1.age
    p1.age=18
    del p1.age
    
    #我们来瞅瞅到底发生了什么
    print(p1.__dict__)
    print(People.__dict__)
    
    #补充
    print(type(p1) == People) #type(obj)其实是查看obj是由哪个类实例化来的
    print(type(p1).__dict__ == People.__dict__)
    
    1. 高级
    • call
    
    
    • iter
    
    
    • enter/exit
    
    
    • metaclass
    
    
    1. 双下"_ _"方法汇总一下
      1. 基础
    • getattr/setattr/delattrgetattribute

    定义了__getattr__(),当访问object不存在的属性时会调用该方法
    不定义访问不存在的属性时会报 AttributeError

  • 相关阅读:
    C#字符串加密解密
    使用AddLayer方法加载shp文件中使用的Map、Dataset等对象详解
    【解决方案】无法嵌入互操作的问题
    简单了解工作空间工厂(IWorkspaceFactory)
    解决VS2017授权问题及没有Add ArcGIS License Checking问题
    ArcGIS Engine中C#开发不能引用ESRI.ArcGIS.AxControls问题
    最简单的ArcGIS Engine应用程序(终)
    最简单的ArcGIS Engine应用程序(下)
    最简单的ArcGIS Engine应用程序(中)
    最简单的ArcGIS Engine应用程序(上)
  • 原文地址:https://www.cnblogs.com/amize/p/14686338.html
Copyright © 2020-2023  润新知