Я недавно прочитал о getattr()
функции . Проблема в том, что я до сих пор не могу понять идею его использования. Единственное, что я понимаю getattr()
, getattr(li, "pop")
это то же самое, что звонить li.pop
.
Я не понял, когда в книге упоминалось, как вы используете ее, чтобы получить ссылку на функцию, не зная ее имени до времени выполнения. Может быть, это я нуб в программировании, в целом. Может ли кто-нибудь пролить свет на эту тему? Когда и как мне это использовать?
Ответы:
getattr(object, 'x')
полностью эквивалентна кobject.x
.Есть только два случая, где
getattr
может быть полезно.object.x
, потому что вы не знаете заранее, какой атрибут вы хотите (это происходит из строки). Очень полезно для метапрограммирования.object.y
поднимет,AttributeError
если нетy
. Ноgetattr(object, 'y', 5)
вернется5
.источник
Объекты в Python могут иметь атрибуты - атрибуты данных и функции для работы с ними (методы). На самом деле, каждый объект имеет встроенные атрибуты.
Например у вас есть объект
person
, который имеет несколько атрибутов:name
,gender
и т.д.Доступ эти атрибуты (будь то методы или объекты данных) обычно пишу:
person.name
,person.gender
,person.the_method()
и т.д.Но что, если вы не знаете имя атрибута во время написания программы? Например, у вас есть имя атрибута, хранящееся в переменной с именем
attr_name
.если
тогда вместо того чтобы писать
ты можешь написать
Некоторая практика:
getattr
повысится,AttributeError
если атрибут с данным именем не существует в объекте:Но вы можете передать значение по умолчанию в качестве третьего аргумента, который будет возвращен, если такой атрибут не существует:
Вы можете использовать
getattr
вместе с,dir
чтобы перебрать все имена атрибутов и получить их значения:Практическим использованием этого было бы найти все методы, имена которых начинаются с,
test
и вызвать их .Аналогично
getattr
существует ,setattr
которая позволяет установить атрибут объекта , имеющего свое название:источник
getattr(..)
следует использовать в 2 сценариях: 1. когда имя атрибута является значением внутри переменной (напримерgetattr(person, some_attr)
) и 2. когда нам нужно использовать третий позиционный аргумент для значения по умолчанию (например,getattr(person, 'age', 24)
). Если я вижу такой сценарий, какgetattr(person, 'age')
мне кажется, он идентичен, иperson.age
это заставляет меня думать, чтоperson.age
это более Pythonic. Это правильно?Для меня
getattr
проще всего объяснить это так:Это позволяет вам вызывать методы на основе содержимого строки вместо того, чтобы вводить имя метода.
Например, вы не можете сделать это:
потому что х не типа
builtin
, ноstr
. Тем не менее, вы можете сделать это:Это позволяет вам динамически связываться с объектами на основе вашего ввода. Я нашел это полезным при работе с пользовательскими объектами и модулями.
источник
Довольно распространенный вариант использования
getattr
является сопоставление данных с функциями.Например, в веб-среде, такой как Django или Pylons,
getattr
упрощается сопоставление URL-адреса веб-запроса с функцией, которая будет его обрабатывать. Например, если вы загляните за пределы маршрутизации Pylons, то увидите, что (по крайней мере, по умолчанию) он разбивает URL-адрес запроса, например:в «клиентов» и «список». Затем он ищет класс контроллера с именем
CustomerController
. Предполагая, что он находит класс, он создает экземпляр класса и затем использует егоgetattr
для полученияlist
метода. Затем он вызывает этот метод, передавая ему запрос в качестве аргумента.Как только вы поймете эту идею, станет действительно легко расширить функциональность веб-приложения: просто добавьте новые методы в классы контроллера, а затем создайте ссылки на своих страницах, которые используют соответствующие URL-адреса для этих методов. Все это стало возможным благодаря
getattr
.источник
Вот быстрый и грязный пример того, как класс может запускать разные версии метода сохранения в зависимости от того, какую операционную систему он использует
getattr()
.Теперь давайте используем этот класс в примере:
источник
Кроме всех удивительных ответов здесь, есть способ использовать
getattr
обширные строки кода и сохранять его аккуратным. Эта мысль пришла после ужасного представления кода, который иногда может быть необходимостью.сценарий
Предположим, что ваша структура каталогов выглядит следующим образом:
И у вас есть функции для получения информации о
Thor
,Iron Man
,Doctor Strange
вsuperheroes.py
. Вы очень умно записываете их свойстваproperties.py
в компактном видеdict
и затем получаете к ним доступ.properties.py
Теперь предположим, что вы хотите вернуть возможности каждого из них по запросу
superheroes.py
. Итак, есть такие функции, как... и другие функции, возвращающие различные значения на основе ключей и супергероя.
С помощью
getattr
вы можете сделать что-то вроде:Вы значительно сократили количество строк кода, функций и повторений!
Да, и, конечно, если у вас есть плохие имена, например,
properties_of_thor
для переменных, их можно создать и получить к ним доступ, просто выполнивПРИМЕЧАНИЕ. Для этой конкретной проблемы могут быть более разумные способы справиться с ситуацией, но идея состоит в том, чтобы дать представление об использовании
getattr
в нужных местах для написания более чистого кода.источник
источник
Я иногда использую,
getattr(..)
чтобы лениво инициализировать атрибуты второстепенной важности непосредственно перед их использованием в коде.Сравните следующее:
К этому:
Преимущество второго способа заключается в том, что он
n_calls_to_plot
появляется только в том месте кода, где он используется. Это хорошо для читабельности, потому что (1) вы можете сразу увидеть, с какого значения он начинается, когда читаете, как он используется, (2) он не отвлекает внимание на__init__(..)
метод, что в идеале должно касаться концептуального состояния класса , а не некоторый служебный счетчик, который используется только одним из методов функции по техническим причинам, таким как оптимизация, и не имеет никакого отношения к значению объекта.источник
Довольно часто, когда я создаю файл XML из данных, хранящихся в классе, я часто получаю ошибки, если атрибут не существует или имеет тип
None
. В этом случае моя проблема заключалась не в том, чтобы знать, каково было имя атрибута, как указано в вашем вопросе, а в том, что данные когда-либо хранились в этом атрибуте.Если бы я использовал
hasattr
это, он бы возвратился,True
даже если значение атрибута было типа,None
и это вызвалоset
бы сбой моей команды ElementTree .Если значение атрибута имеет тип
None
,getattr
также будет возвращать его, что приведетset
к сбою моей команды ElementTree .Я использую следующий метод, чтобы позаботиться об этих случаях сейчас:
Это когда и как я использую
getattr
.источник
Еще одно использование getattr () для реализации оператора switch в Python. Он использует оба отражения, чтобы получить тип дела.
источник
SetAttr ()
Мы используем setattr для добавления атрибута в наш экземпляр класса. Мы передаем экземпляр класса, имя атрибута и значение.
GetAttr ()
С getattr мы получаем эти значения
Например
источник
Я думаю, этот пример говорит сам за себя. Он запускает метод первого параметра, имя которого указано во втором параметре.
источник
Это также уточняется из https://www.programiz.com/python-programming/methods/built-in/getattr
Возраст: 23
Возраст: 23
Пол: мужской
AttributeError: у объекта «Person» нет атрибута «sex»
источник
Я пробовал в Python2.7.17
Некоторые из товарищей уже ответили. Однако я пытался вызвать getattr (obj, 'set_value'), и это не выполняло метод set_value, поэтому я перешел на getattr (obj, 'set_value') () -> Это помогает вызывать то же самое.
Пример кода:
Пример 1:
источник