Python笔记:getattr,__getattr__,__getattribute__

1. getattr(obj,name,default)

    等同于obj.name

2. __getattr__(self, name)

    当对象中找不到相应的属性时,调用该函数

3. __getattribute__(self, name)

   访问对象的所有属性、方法(非系统预定义的),都会调用该方法来访问对应的属性(方法),

 

#!/usr/bin/env python
#-*- coding:utf-8 -*-

"""测试__getattr__,getattr,__getattribute__函数的调用"""

class Test(object):
    s_A = 0
    def __init__(self,*args,**kwargs):
        self.m_a = 9

    def __getattr__(self, name):
        print("Invoked class Test __getattr__ method")
        return "%s from Test __getattr__"%name

    def __getattribute__(self, name):
        print("Invoked class Test __getattribute__ method")
        return super(Test, self).__getattribute__(name)

    def __get__(self, owner_instance, owner_class):
        print("self:%s, id:%s"%(self,id(self)))
        print("instance:%s, id:%s"%(owner_instance, id(owner_instance)))
        print("owner:%s, id:%s"%(owner_class,id(owner_class)))
        return self
                               
    def printId(self):         
        print id(self)         
                               
class Test2(object):           
    m = Test()     
                   

if __name__=='__main__':
    t = Test()
    t2 = Test2()

    t.s_A
    #>>Invoked class Test __getattribute__ method
    #>>0
    t.b
    #>>Invoked class Test __getattribute__ method
    #>>Invoked class Test __getattr__ method
    #>>b from Test __getattr__
    t.printId()
    #>>Invoked class Test __getattribute__ method
    #>>4404408848
    t2.m
    #>>self:, id:4404408848
    #>>instance:<__main__.Test object at 0x10685f310>, id:4404409104
    #>>owner:, id:140590525696752
    #>>
#-*- encoding:utf-8 -*-
class T(object):
    def __init__(self, x):
        self.x = x
        self.__y = 1

    def __getattr__(self, k): #定义当访问不存在的属性时的行为,注意是不存在的属性
        print("in getattr:%s"%k)
        if k == "ok":
            return "no attr"
        elif k in self.__dict__:
            return self.__dict__[k]
        else:
            raise AttributeError("no attr:%s"%k)

    def __delattr__(self, k):
        print("in delattr:%s"%k)
        del self.__dict__[k]

    def __setattr__(self, k, v): #定义了设置属性时的行为,包括在 __init__ 初始化函数中的设置行为,这里获取self.__dict__会调用__getattribute__
        print("in setattr:%s-%s"%(k, v))
        if k == "ok":
            print("can not set attr:ok")
        else:
            self.__dict__[k] = v

    def __getattribute__(self, k): #定义了所有属性访问的行为,注意是所有; 调用魔法函数除外,触发AttributeError时,会调用__getattr__
        print("in __getattribute__:%s"%k)
        if k == "ok":
            raise AttributeError("no attr:ok") #当引发AttributeError时,会调用__getattr__
        else:
            return super(T, self).__getattribute__(k) #注意这块

    def Print(self): #即使调用函数,也会触发__getattribute__函数的调用,
        print("[%d]-%d"%(id(self), self.x))

    def __int__(self):
        return self.x

    def __hex__(self):
        return hex(self.x)

class Singleton(object):
    __instance = None
    def __new__(cls, *args, **kwargs):
        if not cls.__instance:
            print("in __new__:%s, %s, %s"%(cls, str(args), str(kwargs)))
            cls.__instance = super(Singleton, cls).__new__(cls, *args, **kwargs)
            #cls.__instance = object.__new__(cls, *args, **kwargs) #同上
            #cls.__instance = object.__new__(object) #返回的不是cls的实例,所以不会调用__init__方法初始化
        return cls.__instance #返回本类的实例,会调用__init__方法

    def __init__(self, *args, **kwargs):
        print("in __init__:%s, %s"%(str(args), str(kwargs)))

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(python,python,getattr,__getattr__)