首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >python __getattr__帮助

python __getattr__帮助
EN

Stack Overflow用户
提问于 2011-01-16 23:26:51
回答 3查看 3.8K关注 0票数 1

在读一本书的时候,我发现了这段代码...

代码语言:javascript
复制
# 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(类)不同)

我们非常感谢您的帮助:)

EN

回答 3

Stack Overflow用户

发布于 2011-01-16 23:33:47

在您的

  • 中,您实例化一个分配给self.person.

  • You的Person对象,然后覆盖管理器实例上的属性查找(通过为该类实现__getattr__ ),并将这些属性重定向为在self.person变量上查找(在此特定情况下,该变量是1中的Person对象)。

就像Felix Kling在评论中提到的那样,让Manager继承Person会更有意义。在上面的当前代码中,看起来经理有一个人,而更符合逻辑的是认为经理是一个人。

你可以这样做:

代码语言:javascript
复制
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
票数 2
EN

Stack Overflow用户

发布于 2011-01-16 23:32:08

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

init方法中,将self.person绑定到Person的一个实例。现在,每个Manager实例都将拥有这个数据成员。

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

票数 0
EN

Stack Overflow用户

发布于 2011-01-17 06:08:59

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

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

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

理解__getattr_()是访问与任何对象相关的数据和方法的第一步,这一点也很重要。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4706173

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档