getattr()到底是什么?应该如何使用它?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (5)
  • 关注 (0)
  • 查看 (113)

读到 getattr()功能

仍然不能理解它的用法

有木有大神可以解释下呢?

提问于
用户回答回答于

下面是一个快速而肮脏的示例,说明一个类如何激发不同版本的保存方法,具体取决于它在使用哪个操作系统时执行的情况。getattr()...

import os

class Log(object):
    def __init__(self):
        self.os = os.name
    def __getattr__(self, name):
        """ look for a 'save' attribute, or just 
          return whatever attribute was specified """
        if name == 'save':
            try:
                # try to dynamically return a save 
                # method appropriate for the user's system
                return getattr(self, self.os)
            except:
                # bail and try to return 
                # a default save method
                return getattr(self, '_save')
        else:
            return getattr(self, name)

    # each of these methods could have save logic specific to 
    # the system on which the script is executed
    def posix(self): print 'saving on a posix machine'
    def nt(self): print 'saving on an nt machine'
    def os2(self): print 'saving on an os2 machine'
    def ce(self): print 'saving on a ce machine'
    def java(self): print 'saving on a java machine'
    def riscos(self): print 'saving on a riscos machine'
    def _save(self): print 'saving on an unknown operating system'

    def which_os(self): print os.name

现在,让我们在一个示例中使用这个类:

logger = Log()

# Now you can do one of two things:
save_func = logger.save
# and execute it, or pass it along 
# somewhere else as 1st class:
save_func()

# or you can just call it directly:
logger.save()

# other attributes will hit the else 
# statement and still work as expected
logger.which_os()
用户回答回答于

例如,在像Django或Pylons这样的网络框架中,getattr使映射Web请求的URL到要处理它的函非常简单。

只需向控制器类添加新方法,然后在页面中创建链接,为这些方法使用适当的URL。

用户回答回答于

getattr应该是最简单的解释方式:

它允许您根据字符串的内容调用方法,而不是键入方法名称。

例如:

obj = MyObject()
for x in ['foo', 'bar']:
    obj.x()

但是,可以这样做:

obj = MyObject()
for x in ['foo', 'bar']:
    getattr(obj, x)()
用户回答回答于

例如,有一个对象person,它具有以下几个属性:name,,,gender

可以访问这些属性(无论是方法还是数据对象),通常编写:person.name,,,person.gender,,,person.the_method()

但是,如果在编写程序时不知道该属性的名称怎么办?

比如

attr_name = 'gender'

可以这么搞

gender = person.gender

也可以写成

gender = getattr(person, attr_name)

一些常见的做法:

Python 3.4.0 (default, Apr 11 2014, 13:05:11)

>>> class Person():
...     name = 'Victor'
...     def say(self, what):
...         print(self.name, what)
... 
>>> getattr(Person, 'name')
'Victor'
>>> attr_name = 'name'
>>> person = Person()
>>> getattr(person, attr_name)
'Victor'
>>> getattr(person, 'say')('Hello')
Victor Hello

getattrAttributeError

>>> getattr(person, 'age')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Person' object has no attribute 'age'

可以传递一个默认值作为第三个参数:

>>> getattr(person, 'age', 0)
0

可以用getattrdir迭代所有属性名并获取它们的值:

>>> dir(1000)
['__abs__', '__add__', ..., '__trunc__', '__xor__', 'bit_length', 'conjugate', 'denominator', 'from_bytes', 'imag', 'numerator', 'real', 'to_bytes']

>>> obj = 1000
>>> for attr_name in dir(obj):
...     attr_value = getattr(obj, attr_name)
...     print(attr_name, attr_value, callable(attr_value))
... 
__abs__ <method-wrapper '__abs__' of int object at 0x7f4e927c2f90> True
...
bit_length <built-in method bit_length of int object at 0x7f4e927c2f90> True
...

>>> getattr(1000, 'bit_length')()
10

>>> setattr(person, 'name', 'Andrew')
>>> person.name  # accessing instance attribute
'Andrew'
>>> Person.name  # accessing class attribute
'Victor'
>>>

所属标签

可能回答问题的人

  • 学生

    3 粉丝476 提问7 回答
  • uncle_light

    5 粉丝518 提问6 回答
  • o o

    4 粉丝494 提问5 回答
  • 富有想象力的人

    3 粉丝0 提问5 回答

扫码关注云+社区

领取腾讯云代金券