wat betekent/doet de variabele __file__?

Ik verbind deze meestal gewoon met het daadwerkelijke pad. Maar er is een reden voor deze verklaringen die het pad bepalen tijdens runtime, en ik zou de module os.pathheel graag willen begrijpen, zodat ik deze kan gaan gebruiken.


Antwoord 1, autoriteit 100%

Wanneer een module wordt geladen vanuit een bestand in Python, wordt __file__ingesteld op zijn pad. Je kunt dat dan gebruiken met andere functies om de map te vinden waarin het bestand zich bevindt.

Uw voorbeelden één voor één nemen:

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.

U kunt hier de verschillende waarden zien die hieruit worden geretourneerd:

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__)))

en zorg ervoor dat u het vanaf verschillende locaties uitvoert (zoals ./text.py, ~/python/text.pyenzovoort) om te zien welk verschil dat maakt.


Antwoord 2, autoriteit 32%

Ik wil eerst wat verwarring wegnemen. __file__is geen jokerteken, het is een attribuut. Kenmerken en methoden met dubbele onderstrepingstekens worden door de conventie als “speciaal” beschouwd en dienen een speciaal doel.

http://docs.python.org/reference/datamodel.htmltoont veel van de speciale methoden en attributen, zo niet allemaal.

In dit geval is __file__een attribuut van een module (een moduleobject). In Python is een .pybestand een module. Dus import amoduleheeft een attribuut van __file__wat verschillende dingen betekent onder verschillende omstandigheden.

Genomen uit de documenten:

__file__is de padnaam van het bestand waaruit de module is geladen, als het uit een bestand is geladen. Het kenmerk __file__is niet aanwezig
voor C-modules die statisch zijn gekoppeld aan de interpreter; voor
uitbreidingsmodules dynamisch geladen vanuit een gedeelde bibliotheek, is het de
padnaam van het gedeelde bibliotheekbestand.

In jouw geval heeft de module toegang tot zijn eigen __file__attribuut in de globale naamruimte.

Probeer om dit in actie te zien:

# file: test.py
print globals()
print __file__

En ren:

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

Antwoord 3, autoriteit 11%

Volgens de documentatie:

__file__is de padnaam van het bestand waaruit de module was
geladen, als het uit een bestand is geladen. Het kenmerk __file__is niet
aanwezig voor C-modules die statisch zijn gekoppeld aan de interpreter;
voor uitbreidingsmodules die dynamisch worden geladen vanuit een gedeelde bibliotheek, is het:
de padnaam van het gedeelde bibliotheekbestand.

en ook:

__file__moet het pad naar het bestand zijn, tenzij de module is ingebouwd (en dus wordt vermeld in sys.builtin_module_names), in welk geval het attribuut is niet ingesteld.


Antwoord 4, autoriteit 6%

Door __file__te gebruiken in combinatie met verschillende os.path-modules, kunnen alle paden relatief zijn ten opzichte van de maplocatie van de huidige module. Hierdoor kunnen uw modules/projecten overdraagbaar zijn naar andere machines.

In uw project doet u:

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

en probeer het vervolgens op uw server te implementeren met een implementatiemap zoals /home/web/mydevproject/, dan kan uw code de paden niet correct vinden.


Antwoord 5, autoriteit 5%

Ik wil hier even een korte opmerking toevoegen (meestal antwoord op de titel van de vraag in plaats van de beschrijving) over een verandering die sommige mensen in verwarring kan brengen. Vanaf Python 3.4 is er een kleine verandering opgetreden in hoe de __file__zich gedraagt:

  • Het is ingesteld op het relatieve pad van de module waarin het wordt gebruikt, als die module direct wordt uitgevoerd.
  • Anders is het ingesteld op het absolute pad van het bestand.

Module __file__attributen (en gerelateerde waarden) zouden nu standaard altijd absolute paden moeten bevatten, met als enige uitzondering __main__.__file__wanneer een script direct is uitgevoerd met een relatief pad. (Bijgedragen door Brett Cannon in uitgave 18416.)

Voorbeeld:

Module x direct aanroepen en module y indirect:

# x.py:
from pathlib import Path
import y
print(__file__)
print(Path(__file__))
print(Path(__file__).resolve())
# y.py:
from pathlib import Path
print(__file__)
print(Path(__file__))

Als python3 x.pywordt uitgevoerd, wordt het volgende uitgevoerd:

/home/aderchox/mytest/y.py                                                                                                                       
/home/aderchox/mytest/y.py                                                                                                                       
x.py                                                                                                                                             
x.py                                                                                                                                             
/home/aderchox/mytest/x.py

Other episodes