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)))