Я прочитал статью об 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.
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 для перебора всех имен атрибутов и получения их значений:
Есть только два случая, где 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.