#python #getattr
#python #getattr
Вопрос:
Работает следующий код:
class Foo:
def run_this(self):
print("ran this")
ff = Foo()
method = getattr(ff, "run_this")
method()
--
run_this
Но я не понимаю, почему. Если getattr возвращает объект функции, мне нужно передать self
объект в качестве первого аргумента. Кажется, что method
это все-таки не объект функции, но я не уверен, что это такое. Почему self передается при вызове method()
?
В документах говорится только
getattr(объект, имя [, по умолчанию]) Возвращает значение именованного атрибута объекта. имя должно быть строкой. Если строка является именем одного из атрибутов объекта, результатом является значение этого атрибута. Например, getattr(x, `foobar`) эквивалентно x.foobar . Если именованный атрибут не существует, возвращается значение по умолчанию, если оно указано, в противном случае возникает ошибка AttributeError .
Таким образом, они отвечают на вопрос «что происходит», но не на вопрос о том, почему это работает таким образом.
Комментарии:
1.
getattr(obj, 'method')()
не нуждается вself
аргументе по той же причинеobj.method()
, что и нет — он уже привязан к объекту при поиске атрибута. Без объяснения того, почему, по вашему мнениюgetattr
, строковый литерал должен вести себя иначе, чем обычный доступ к атрибутам, я не уверен, какой другой ответ вас удовлетворит.2.
getattr(obj, 'method')
возвращает «связанный метод», который по сути является тем же самым,functools.partial
что и метод с первым аргументом, связанным сobj
3. Потому что это эквивалентно
method = ff.run_this
, который по той же причине не требуетсяself
в качестве аргумента. По той же причинеff.run_this()
нет4. Если вы хотите понять, как все это работает в принципе, вам нужно понимать, что функциональные объекты — это дескрипторы,
__get__
метод которых частично применяет экземпляр при обращении к экземпляру. Прочитайте следующее: docs.python.org/3/howto/descriptor.html