Почему импортированная функция «как» другого имени сохраняет свое исходное имя __name__? - PullRequest
0 голосов
/ 13 ноября 2018

Здесь:

from os.path import exists as foo
print foo.__name__

получаем: 'exists'.Почему не 'foo'?Какой атрибут даст 'foo'?

Ответы [ 3 ]

0 голосов
/ 13 ноября 2018

as является синтаксическим сахаром в файле / сеансе импорта, а атрибут __name__ является частью объекта функции.

0 голосов
/ 13 ноября 2018

Импортирование объекта просто связывает новую переменную , и все, что делает добавление as newname, позволяет вам выбрать альтернативное имя для использования в переменной в текущем пространстве имен.

Атрибут __name__ объекта ничего не говорит об имени, с которым он в данный момент связан, вы можете иметь любое количество переменных, а также контейнеры, такие как списки или словари, указывающие на один и тот же объект, в конце концов:

def foo(): pass

bar = foo
spam = foo
list_of_functions = [foo]
dictionary_of_functions = {'monty': foo, 'python': foo}

Выше создано 4 дополнительных ссылки на объект функции; foo.__name__ не может отражать все эти элементы, а ссылки в list_of_functions и dictionary_of_functions (напрямую) не имеют имен.

Поскольку import foo, import bar as foo, from module import foo и from module import bar as foo все просто устанавливают имя foo в текущем модуле, они обрабатываются точно так же, как и другие назначения. Вы также можете импортировать функцию более одного раза, под разными именами.

Вместо этого __name__ значение функции устанавливается на имя, с которым оно было определено в операторе def <name>(...):. В лучшем случае это помощь при отладке. Например, он используется в трассировках, чтобы упростить идентификацию строк кода, отображаемых в трассировке. Вы можете установить __name__ на что-то другое, только если это поможет лучше определить местоположение. (Примечание: в Python 3 есть также атрибут __qualname_ , который используется вместо __name__, так как он включает больше информации о том, где функция определена, когда вложена или определена в классе).

0 голосов
/ 13 ноября 2018

Вы можете просмотреть import foo as bar как просто назначение.Вы не ожидаете, что функция изменит свой атрибут __name__ при назначении ей другого имени.

>>> def foo(): pass
>>> 
>>> foo.__name__
'foo'
>>> bar = foo
>>> bar.__name__
'foo'

Спасибо.Какой атрибут переменной bar вернет строку 'bar' тогда?

Нет такого атрибута.Имена (bar) относятся к значениям (объекту функции) однонаправленно.

Атрибут __name__ функции устанавливается как имя, для которого была определена функция с использованием синтаксиса
def ....Вот почему вы не получите значимый атрибут __name__, если определите анонимную функцию и назначите имя foo после ее создания.

>>> foo = lambda: None
>>> foo.__name__
'<lambda>'
...