що означає / робить змінну __file__?


177
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, щоб я міг почати його використовувати.

Відповіді:


162

Коли модуль завантажується з файлу в 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__НЕ визначається у всіх випадках, наприклад, статично пов'язані модулі С. Ми не можемо розраховувати, що __file__завжди будуть доступні.
Кріс Джонсон

5
У перекладачі всі приклади повертаються name '__file__' is not defined.
користувач1063287

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.