__setattr__ Python 中的函数
__setattr__ function in Python
我试图通过使用 getattr 和 setattr 函数来理解 Python 中委托的概念。基本思路是先通过 class Professional 在 Person class 中设置属性 'lang' 的值,然后检索相同的值。问题是结果是无限循环。
class Person:
def __init__(self,name='Subhayan',job='Engineer',unique='Unique'):
print ("Inside init function of Person")
self.name = name
self.job = job
self.salary = 50000
self.lang = "Perl"
def __setattr__(self,att,value):
self.__dict__[att] = value
class Professional:
job = 'Engineer'
salary = 75000
def __init__(self):
print ("Inside Professional init function")
self.person = Person()
def __getattr__(self,attr):
print ("Calling the getattr function")
return getattr(self.person, attr)
def __setattr__(self,att,value):
# print ("calling the setattr function setting the value of %s to %s" %(attr,value))
self.person.__setattr__(self,att,value)
if __name__ == '__main__':
print ("Calling the script as main")
Prof = Professional()
print ("Salary is",Prof.salary)
print ("name is",Prof.__class__)
print ("Setting the value of lang")
Prof.lang = 'Python'
value = Prof.lang
print ("The value of lang is ;",value)
__setattr__
和 __getattr__
也适用于您的实例完全初始化之前。在这种情况下,您的线路 self.person = Person()
调用 __setattr__
。然后调用 __getattr__
(因为 self.person
尚未定义),然后再次递归调用 __getattr__
(出于同样的原因)。
有几种解决方法。也许最简单的方法是绕过 __setattr__
对初始 self.person
赋值的调用,例如 super().__setattr__('person', Person())
.
一般来说,您在使用这些方法时需要小心,因为它们的调用频率可能比您意识到的要高。如果您的特殊处理仅适用于少数特定属性,您可能需要使用 property
。
__setattr__
调用all 属性设置。这包括 self.person = Person()
调用 __init__
:
def __init__(self):
print ("Inside Professional init function")
self.person = Person()
这将调用 self.__setattr__('person', Person())
,后者会尝试访问 self.person
,后者随后调用 self.__getattr__('person')
,因为还没有这样的属性。在 __getattr__
中,当您尝试不断访问 self.person
.
时,您将陷入无限循环
您可以测试 __setattr__
中的特定 person
属性(并将其委托给基本实现):
def __setattr__(self, att, value):
# print ("calling the setattr function setting the value of %s to %s" %(attr,value))
if att == 'person':
return super().__setattr__(att, value)
return self.person.__setattr__(self,att,value)
您可能还想在 __getattr__
中添加一个测试;如果使用 person
调用它,则该属性尚未设置,应引发 AttributeError
:
def __getattr__(self,attr):
print ("Calling the getattr function")
if attr == 'person':
raise AttributeError('person')
return getattr(self.person, attr)
我试图通过使用 getattr 和 setattr 函数来理解 Python 中委托的概念。基本思路是先通过 class Professional 在 Person class 中设置属性 'lang' 的值,然后检索相同的值。问题是结果是无限循环。
class Person:
def __init__(self,name='Subhayan',job='Engineer',unique='Unique'):
print ("Inside init function of Person")
self.name = name
self.job = job
self.salary = 50000
self.lang = "Perl"
def __setattr__(self,att,value):
self.__dict__[att] = value
class Professional:
job = 'Engineer'
salary = 75000
def __init__(self):
print ("Inside Professional init function")
self.person = Person()
def __getattr__(self,attr):
print ("Calling the getattr function")
return getattr(self.person, attr)
def __setattr__(self,att,value):
# print ("calling the setattr function setting the value of %s to %s" %(attr,value))
self.person.__setattr__(self,att,value)
if __name__ == '__main__':
print ("Calling the script as main")
Prof = Professional()
print ("Salary is",Prof.salary)
print ("name is",Prof.__class__)
print ("Setting the value of lang")
Prof.lang = 'Python'
value = Prof.lang
print ("The value of lang is ;",value)
__setattr__
和 __getattr__
也适用于您的实例完全初始化之前。在这种情况下,您的线路 self.person = Person()
调用 __setattr__
。然后调用 __getattr__
(因为 self.person
尚未定义),然后再次递归调用 __getattr__
(出于同样的原因)。
有几种解决方法。也许最简单的方法是绕过 __setattr__
对初始 self.person
赋值的调用,例如 super().__setattr__('person', Person())
.
一般来说,您在使用这些方法时需要小心,因为它们的调用频率可能比您意识到的要高。如果您的特殊处理仅适用于少数特定属性,您可能需要使用 property
。
__setattr__
调用all 属性设置。这包括 self.person = Person()
调用 __init__
:
def __init__(self):
print ("Inside Professional init function")
self.person = Person()
这将调用 self.__setattr__('person', Person())
,后者会尝试访问 self.person
,后者随后调用 self.__getattr__('person')
,因为还没有这样的属性。在 __getattr__
中,当您尝试不断访问 self.person
.
您可以测试 __setattr__
中的特定 person
属性(并将其委托给基本实现):
def __setattr__(self, att, value):
# print ("calling the setattr function setting the value of %s to %s" %(attr,value))
if att == 'person':
return super().__setattr__(att, value)
return self.person.__setattr__(self,att,value)
您可能还想在 __getattr__
中添加一个测试;如果使用 person
调用它,则该属性尚未设置,应引发 AttributeError
:
def __getattr__(self,attr):
print ("Calling the getattr function")
if attr == 'person':
raise AttributeError('person')
return getattr(self.person, attr)