1

读一本书,我遇到了这个代码......

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

它做了我想做的事,但我不明白课堂上的__getattr__功能Manager。我知道它代表了Person类的所有其他属性。但我不明白它的工作方式。例如为什么Person上课?因为我没有明确告诉它。人(模块不同于人(类)

非常感谢任何帮助:)

4

3 回答 3

2
  1. 在您的实例中,__init__您实例化了一个Person分配给 self.person 的对象。

  2. 然后,您覆盖 Manager 实例上的属性查找(通过__getattr__为此类实现)并重定向这些属性以在 self.person 变量上查找(Person在这种特殊情况下,它是来自 1 的对象)。

Manager就像评论中提到的 Felix Kling 一样,继承 from会更有意义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-16T15:33:46.670 回答
0

除了阅读一本书之外,您可能还想查阅这本书__getattr__(),您可以在其中找到关于方法如何工作的非常清晰的解释。

简而言之,当没有指定名称的属性附加到它所应用的对象时,它被调用,也没有附加到对象类或其任何超类。换句话说,它在所有其他方法都失败时调用。

在您示例的代码中, 的实现__getattr_()有效地将命名属性的搜索重定向到self.person对象上,该对象是Person类的一个实例。

同样重要的是要了解这__getattr_()是访问与任何对象关联的数据和方法的第一步。

于 2011-01-16T22:08:59.110 回答
0

实际上,您确实明确地告诉它 - 不是通过命名类,而是通过提供该类的实例。

在该init方法中,您绑定self.personPerson. 现在,每个Manager实例都会有这个数据成员。

__getattr__中,您将作为第一个参数委托给getattr内置函数。self.person无论 的类型如何self.person,它都会查找具有给定名称的成员。

于 2011-01-16T15:32:07.813 回答