что означает переменная __file__ / делает?


178
A = os.path.join(os.path.dirname(__file__), '..')

B = os.path.dirname(os.path.realpath(__file__))

C = os.path.abspath(os.path.dirname(__file__))

Я обычно просто связываю их с фактическим путем. Но есть причина для этих утверждений, которые определяют путь во время выполнения, и я действительно хотел бы прервать модуль os.path, чтобы я мог начать использовать его.

Ответы:


163

Когда модуль загружается из файла в Python, __file__устанавливается его путь. Затем вы можете использовать это с другими функциями, чтобы найти каталог, в котором находится файл.

Принимая ваши примеры по одному:

A = os.path.join(os.path.dirname(__file__), '..')
# A is the parent directory of the directory where program resides.

B = os.path.dirname(os.path.realpath(__file__))
# B is the canonicalised (?) directory where the program resides.

C = os.path.abspath(os.path.dirname(__file__))
# C is the absolute path of the directory where the program resides.

Вы можете увидеть различные значения, возвращаемые из них здесь:

import os
print(__file__)
print(os.path.join(os.path.dirname(__file__), '..'))
print(os.path.dirname(os.path.realpath(__file__)))
print(os.path.abspath(os.path.dirname(__file__)))

и убедитесь, что вы запускаете его из разных мест (например ./text.py, ~/python/text.pyи т. д.), чтобы увидеть, что это меняет.


7
Хороший ответ, но посмотрите другую важную деталь из других ответов: __file__НЕ определяется во всех случаях, например, статически связанные модули C. Мы не можем рассчитывать на __file__постоянную доступность.
Крис Джонсон

5
В интерпретаторе все примеры возвращаются name '__file__' is not defined.
user1063287 25.11.14

10
@ user1063287 Посмотрите на ответ DemoUser; __file__путь к файлу, из которого был загружен модуль, если он был загружен из файла. Это означает, что __file__будет работать только тогда, когда вы запускаете его как скрипт, а не в интерпретаторе. (Если вы не импортируете его в интерпретатор ...)
МОЛОДОЙ

59

Я просто хочу сначала устранить некоторую путаницу. __file__это не подстановочный знак, это атрибут. Атрибуты и методы двойного подчеркивания считаются «специальными» по соглашению и служат специальной цели.

http://docs.python.org/reference/datamodel.html показывает многие специальные методы и атрибуты, если не все.

В данном случае __file__это атрибут модуля (объект модуля). В Python .pyфайл является модулем. Так import amoduleбудет иметь атрибут, __file__который означает разные вещи в разных обстоятельствах.

Взято из документов:

__file__путь к файлу, из которого был загружен модуль, если он был загружен из файла. __file__Атрибут отсутствует для модулей C, которые статически связаны в интерпретатор; для модулей расширения, загружаемых динамически из общей библиотеки, это путь к файлу общей библиотеки.

В вашем случае модуль обращается к своему __file__ атрибуту в глобальном пространстве имен.

Чтобы увидеть это в действии, попробуйте:

# file: test.py

print globals()
print __file__

И запустить:

python test.py

{'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', '__file__':
 'test_print__file__.py', '__doc__': None, '__package__': None}
test_print__file__.py

23

Согласно документации :

__file__путь к файлу, из которого был загружен модуль, если он был загружен из файла. __file__Атрибут отсутствует для модулей C, которые статически связаны в интерпретатор; для модулей расширения, загружаемых динамически из общей библиотеки, это путь к файлу общей библиотеки.

а также :

__file__должен быть «путем» к файлу, если модуль не является встроенным (и, следовательно, указан в нем sys.builtin_module_names), в этом случае атрибут не устанавливается.


13

Использование в __file__сочетании с различными os.pathмодулями позволяет всем путям относиться к местоположению каталога текущего модуля. Это позволяет переносить ваши модули / проекты на другие машины.

В своем проекте вы делаете:

A = '/Users/myname/Projects/mydevproject/somefile.txt'

а затем попытайтесь развернуть его на своем сервере с помощью каталога развертываний, подобного /home/web/mydevproject/которому ваш код не сможет правильно найти пути.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.