Вопрос-Ответ

What is & How to use getattr() in Python?

Что такое и как использовать getattr() в Python?

Я прочитал статью об getattr функции, но я все еще не могу понять, для чего она нужна.

Единственное, что я понимаю о getattr() том, что getattr(li, "pop") это то же самое, что и вызов li.pop.

Когда и как мне использовать именно это? В книге что-то говорилось об использовании этого для получения ссылки на функцию, имя которой неизвестно до времени выполнения, но когда и зачем мне это использовать?

Переведено автоматически
Ответ 1

Объекты в Python могут иметь атрибуты - атрибуты данных и функции для работы с ними (методы). На самом деле, у каждого объекта есть встроенные атрибуты (попробуйте dir(None), dir(True), dir(...), dir(dir) в консоли Python).

Например, у вас есть объект person, который имеет несколько атрибутов: name, gender и т.д.

Вы получаете доступ к этим атрибутам (будь то методы или объекты данных) обычно написав: person.name, person.gender, person.the_method() и т.д.

Но что, если вы не знаете имени атрибута на момент написания программы? Например, имя атрибута хранится в переменной с именем attr_name.

если

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

getattr вызовет, AttributeError если атрибут с заданным именем не существует в объекте:

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

Вы можете использовать getattr вместе с dir для перебора всех имен атрибутов и получения их значений:

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

Практическим применением этого было бы найти все методы, имена которых начинаются с test и вызвать их.

Аналогично getattr there is setattr, которая позволяет вам установить атрибут объекта, имеющий его имя:

>>> setattr(person, 'name', 'Andrew')
>>> person.name # accessing instance attribute
'Andrew'
>>> Person.name # accessing class attribute
'Victor'
>>>
Ответ 2

getattr(object, 'x') полностью эквивалентна object.x.

Есть только два случая, где getattr это может быть полезно.


  • вы не можете писать object.x, потому что заранее не знаете, какой атрибут вам нужен (он берется из строки). Очень полезно для метапрограммирования.

  • вы хотите указать значение по умолчанию. object.y вызовет AttributeError, если его нет y. Но getattr(object, 'y', 5) вернет 5.

Ответ 3

Для меня getattr проще всего объяснить таким образом:

Она позволяет вызывать методы на основе содержимого строки вместо ввода имени метода.

Например, вы не можете этого сделать:

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

потому что x не имеет типа builtin, но str . Однако вы МОЖЕТЕ сделать это:

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

Это позволяет вам динамически подключаться к объектам на основе ваших входных данных. Я нашел это полезным при работе с пользовательскими объектами и модулями.

Ответ 4

Довольно распространенный вариант использования для getattr - это преобразование данных в функции.

Например, в веб-фреймворке, таком как Django или Pylons, getattr позволяет легко сопоставить URL веб-запроса с функцией, которая будет его обрабатывать. Если вы заглянете под капот маршрутизации Pylons, например, вы увидите, что (по крайней мере, по умолчанию) она обрабатывает URL запроса, например:

http://www.example.com/customers/list

в "customers" и "list". Затем выполняется поиск класса контроллера с именем CustomerController. Предполагая, что она находит класс, она создает экземпляр класса, а затем использует getattr для получения своего list метода. Затем она вызывает этот метод, передавая ему запрос в качестве аргумента.

Как только вы поймете эту идею, расширить функциональность веб-приложения станет действительно легко: просто добавьте новые методы в классы контроллеров, а затем создайте ссылки на своих страницах, которые используют соответствующие URL-адреса для этих методов. Все это стало возможным благодаря getattr.

python function