喵喵时光机
让我们看看这两个方面的一些简单示例。__getattr__和__getattribute__神奇的方法。__getattr__Python会调用__getattr__方法,只要请求尚未定义的属性。在下面的示例中,我的类数数无__getattr__方法。现在,主要是当我试图访问两个obj1.mymin和obj1.mymax属性一切都很好。但当我试图进入obj1.mycurrent属性-Python给了我AttributeError: 'Count' object has no attribute 'mycurrent'class Count():
def __init__(self,mymin,mymax):
self.mymin=mymin
self.mymax=mymax
obj1 = Count(1,10)print(obj1.mymin)print(obj1.mymax)print(obj1.mycurrent) --> AttributeError: 'Count' object has no attribute 'mycurrent'现在我的课数数有__getattr__方法。现在当我试图访问obj1.mycurrent属性-python返回我在__getattr__方法。在我的示例中,每当我试图调用不存在的属性时,python将创建该属性并将其设置为整数值0。class Count:
def __init__(self,mymin,mymax):
self.mymin=mymin
self.mymax=mymax
def __getattr__(self, item):
self.__dict__[item]=0
return 0obj1 = Count(1,10)print(obj1.mymin)print(obj1.mymax)print(obj1.mycurrent1)__getattribute__现在让我们看看__getattribute__方法。如果你有__getattribute__方法在类中,python对每个属性调用此方法,不管它是否存在。所以为什么我们需要__getattribute__方法?一个很好的原因是,您可以阻止对属性的访问,并使它们更加安全,如下面的示例所示。每当有人试图访问我的属性时,都以子字符串开头。‘cur’Python引发AttributeError例外。否则,它将返回该属性。class Count:
def __init__(self,mymin,mymax):
self.mymin=mymin
self.mymax=mymax
self.current=None
def __getattribute__(self, item):
if item.startswith('cur'):
raise AttributeError
return object.__getattribute__(self,item)
# or you can use ---return super().__getattribute__(item)obj1 = Count(1,10)print(obj1.mymin)print(obj1.mymax)print(obj1.current)重要:为了避免无限递归__getattribute__方法时,它的实现应该始终调用同名的基类方法来访问它需要的任何属性。例如:object.__getattribute__(self, name)或super().__getattribute__(item)而不是self.__dict__[item]重要如果您的类同时包含两个盖塔和getAttribute魔法方法__getattribute__被称为第一个。但如果__getattribute__提高AttributeError异常,则该异常将被忽略,并且__getattr__方法将被调用。请参见以下示例:class Count(object):
def __init__(self,mymin,mymax):
self.mymin=mymin
self.mymax=mymax
self.current=None
def __getattr__(self, item):
self.__dict__[item]=0
return 0
def __getattribute__(self, item):
if item.startswith('cur'):
raise AttributeError
return object.__getattribute__(self,item)
# or you can use ---return super().__getattribute__(item)
# note this class subclass objectobj1 = Count(1,10)print(obj1.mymin)print(obj1.mymax)print(obj1.current)