在读一本书的时候,我发现了这段代码...
# module person.py
class Person:
def __init__(self, name, job=None, pay=0):
self.name = name
self.job = job
self.pay = pay
def lastName(self):
return self.name.split()[-1]
def giveRaise(self, percent):
self.pay = int(self.pay *(1 + percent))
def __str__(self):
return "[Person: %s, %s]" % (self.name,self.pay)
class Manager():
def __init__(self, name, pay):
self.person = Person(name, "mgr", pay)
def giveRaise(self, percent, bonus=.10):
self.person.giveRaise(percent + bonus)
def __getattr__(self, attr):
return getattr(self.person, attr)
def __str__(self):
return str(self.person)它做了我想让它做的事情,但是我不理解Manager类中的__getattr__函数。我知道它委托来自Person类的所有其他属性。但我不明白它是怎么工作的。例如,为什么来自Person类?因为我没有明确地告诉它。Person(模块与Person(类)不同)
我们非常感谢您的帮助:)
发布于 2011-01-16 23:33:47
在您的
Person对象,然后覆盖管理器实例上的属性查找(通过为该类实现__getattr__ ),并将这些属性重定向为在self.person变量上查找(在此特定情况下,该变量是1中的Person对象)。就像Felix Kling在评论中提到的那样,让Manager继承Person会更有意义。在上面的当前代码中,看起来经理有一个人,而更符合逻辑的是认为经理是一个人。
你可以这样做:
class Person(object):
def __init__(self, name, job=None, pay=0):
self.name = name
self.job = job
self.pay = pay
def give_raise(self, percent):
self.pay = int(self.pay *(1 + percent))
def __str__(self):
return "[Person: %s, %s]" % (self.name, self.pay)
class Manager(Person):
def __init__(self, name, pay):
super(Manager, self).__init__(name, "mgr", pay)
def give_raise(self, percent, bonus=.10):
self.pay = int(self.pay * (1 + (percent + bonus)))
# example usage
John = Person("John", "programmer", 1000)
Dave = Manager("Dave", 2000)
print John, Dave
John.give_raise(.20)
Dave.give_raise(.20)
print John, Dave发布于 2011-01-16 23:32:08
实际上,您确实明确地告诉它-不是通过命名类,而是通过提供该类的实例。
在init方法中,将self.person绑定到Person的一个实例。现在,每个Manager实例都将拥有这个数据成员。
在__getattr__中,您将使用self.person作为第一个参数委托给getattr内置函数。无论self.person的类型是什么,它都会查找具有给定名称的成员。
发布于 2011-01-17 06:08:59
除了阅读一本书之外,您可能还想参考,在那里您可以找到关于__getattr__()方法如何工作的非常清晰的解释。
简而言之,当没有指定名称的属性附加到要应用它的对象,也没有附加到object类或它的任何超类时,它就会被调用。换句话说,当所有其他方法都失败时,它会调用。
在示例的代码中,__getattr_()的实现有效地将对命名属性的搜索重定向到self.person对象上,该对象是Person类的一个实例。
理解__getattr_()是访问与任何对象相关的数据和方法的第一步,这一点也很重要。
https://stackoverflow.com/questions/4706173
复制相似问题