Yanıtlar:
__file__
Geçerli dosyanın adını almak için kullanabilirsiniz . Ana modülde kullanıldığında, başlangıçta çağrılan komut dosyasının adıdır.
Dizin kısmını (varsa) atlamak istiyorsanız, kullanabilirsiniz os.path.basename(__file__)
.
__file__
interaktif tercümanda tanımlanmamıştır, çünkü orada anlamsızdır. İçe aktarma uygulaması tarafından ayarlanır, bu nedenle standart olmayan bir içe aktarma mekanizması kullanırsanız da ayarlanmamış olabilir.
import os
çalışması için bir gerekli olduğuna inanıyorum . Bunu cevaba eklerdim.
import os
ve import os.path
tamamen eşdeğerdir.
import sys
print sys.argv[0]
Bu yazdırılacaktır foo.py
için python foo.py
, dir/foo.py
için python dir/foo.py
bu ilk argüman var vb python
. (Py2exe sonra olacağını unutmayın foo.exe
.)
python linkfile.py
, nereye linkfile.py
sembolik köprü ise realfile.py
, sys.argv[0]
olacak 'linkfile.py'
ya ne istediğinizi olabilir veya olmayabilir; kesinlikle beklediğim bu . __file__
aynı: olacak linkfile.py
. Eğer bulmak istiyorsanız 'realfile.py'
den 'linkfile.py'
deneyin os.path.realpath('linkfile.py')
.
__file__
onun yerine kullanın.
Tamlık uğruna, çeşitli olası sonuçları özetlemeye ve her birinin tam davranışı için referanslar sağlamaya değeceğini düşündüm:
__file__
resmi belgelerde ayrıntılı olarak açıklandığı gibi şu anda yürütülen dosyadır :
__file__
bir dosyadan yüklendiyse modülün yüklendiği dosyanın yol adıdır.__file__
Nitelik gibi modülleri, belirli türleri için eksik olabilir C statik tercüman içine bağlantılı modüllerin; paylaşılan bir kitaplıktan dinamik olarak yüklenen uzantı modülleri için, paylaşılan kitaplık dosyasının yol adıdır.
Python3.4 itibaren itibaren, başına konuyla 18416 , __file__
şu anda yürütülen dosyası (değil ile tercüman aracılığıyla doğrudan idam edilmiş bir senaryo olmadığı sürece, her zaman mutlak bir yoldur -m
göreli bir yol kullanarak komut satırı seçeneği).
__main__.__file__
(içe aktarmayı gerektirir __main__
) ana modülün , örneğin komut satırından çağrılan komut dosyasının yukarıda belirtilen __file__
özniteliğine erişir .
sys.argv[0]
(içe aktarmayı gerektirir sys
) komut satırından çağrılan komut dosyası adıdır ve resmi belgelerde ayrıntılı olarak açıklandığı gibi mutlak bir yol olabilir :
argv[0]
komut dosyası adıdır (bunun tam yol adı olup olmadığı işletim sistemine bağlıdır). Komut-c
yorumlayıcıya komut satırı seçeneği kullanılarak yürütüldüyseargv[0]
, dizeye ayarlanır'-c'
. Python yorumlayıcısına komut dosyası adı geçmediyseargv[0]
, boş dizedir.
Bahsedildiği gibi bu soruya başka bir cevap , Python gibi araçları vasıtasıyla tek başına çalıştırılabilir programlara dönüştürüldü komut py2exe veya PyInstaller bu yaklaşımı kullanırken (yani istenilen sonucu göstermeyebilir sys.argv[0]
adı yerine çalıştırılabilir adını yapacağını yürütülebilir dosya içindeki ana Python dosyasının).
Yukarıda belirtilen seçeneklerin hiçbiri, muhtemelen düzensiz bir içe aktarma işleminden dolayı işe yaramıyorsa, denetleme modülü yararlı olabilir. Özellikle, yürütmesini inspect.getfile(...)
ile inspect.currentframe()
ikinci olsa da, işe yarayabilir geriNone
olmayan bir uygulama çalışırken Python yığın çerçevesi.
Geçerli komut dosyası sembolik bir bağlantıysa, yukarıdakilerin tümü gerçek dosyanın yolu yerine sembolik bağın yolunu döndürür os.path.realpath(...)
ve ikincisini ayıklamak için çağrılmalıdır.
os.path.basename(...)
asıl dosya adını ayıklamak için yukarıdakilerden herhangi birine os.path.splitext(...)
çağrılabilir ve sonekini olduğu gibi kesmek için asıl dosya adına çağrılabilir os.path.splitext(os.path.basename(...))
.
Kaynaktan Python 3.4 itibaren, her PEP 428 , PurePath
sınıf ve pathlib
modülü de yukarıdakilerin herhangi olduğu gibi kullanılabilir. Özellikle, pathlib.PurePath(...).name
gerçek dosya adını alır ve pathlib.PurePath(...).stem
gerçek dosya adını soneki olmadan ayıklar.
Not __file__
ana dosyadan ithal ve farklı olabilir bu kod bulunduğu, yorumlanıyor dosyayı verecektir. Ana dosyayı almak için özel __main__ modülü kullanılabilir:
import __main__ as main
print(main.__file__)
O Not __main__.__file__
taşınabilir hale getirmek için yukarıdaki gibi Python 2.7 değil 3.2 eserler, bu nedenle ithalat-olarak sözdizimi kullanın.
rPython
paketi R
dilden kullandığımda çalışmaz . Bu, ele alınması çok zor olan istisnai bir durum olmalıdır.
__main__
Değişkenleri R
ve arasında geçişte kullanmak için dahili olarak içe aktarır, python
bu nedenle __main__.__file__
başka bir şey çağırmadan önce ayarlanması nispeten kolaydır , ancak bu durumda neyin uygun bir değer olacağından bile emin değilim.
Yukarıdaki cevaplar iyidir. Ancak yukarıdaki sonuçları kullanarak bu yöntemi daha verimli buldum.
Bu, gerçek komut dosyası adının yolla sonuçlanmasına neden olmaz.
import sys
import os
file_name = os.path.basename(sys.argv[0])
Modern Python sürümleri (3.4+) Path(__file__).name
için daha deyimsel olmalıdır. Ayrıca, uzantısız Path(__file__).stem
komut dosyası adını verir .py
.
from pathlib import Path
.
pathlib
Python 3.4'te tanıtıldı, bu yüzden Python 3.4'ten başlamalı .
Dosya adının olduğu varsayıldığında foo.py
, aşağıdaki snippet
import sys
print sys.argv[0][:-3]
veya
import sys
print sys.argv[0][::-1][3:][::-1]
Daha fazla karakter içeren diğer uzantılara gelince, örneğin dosya adı foo.pypy
import sys
print sys.argv[0].split('.')[0]
Mutlak bir yoldan çıkarmak istiyorsanız
import sys
print sys.argv[0].split('/')[-1].split('.')[0]
çıktı olacak foo
__file__
ve sys.argv[0]
Görmekten stackoverflow.com/questions/5851588/...
Sys içindeki ilk argüman geçerli dosya adı olacak, bu yüzden bu işe yarayacak
import sys
print sys.argv[0] # will print the file name
Alışılmadık bir içe aktarma işlemi gerçekleştiriyorsanız (örn., Bir seçenekler dosyasıdır), şunu deneyin:
import inspect
print (inspect.getfile(inspect.currentframe()))
Bunun, dosyanın mutlak yolunu döndüreceğini unutmayın.
uzantı olmadan mevcut komut dosyası adını almak için bunu deneyebiliriz.
import os
script_name = os.path.splitext(os.path.basename(__file__))[0]
tüm bu cevaplar harika, ama bazı problemleri var İlk bakışta göremeyebilirsiniz.
ne istediğimizi tanımlayalım - yürürlükteki modülün adını değil, yürütülen kodun adını istiyoruz - bu nedenle __file__
, içe aktarılan bir modülde değil, yalnızca yürütülen kodda kullanılıyorsa çalışır.
sys.argv
şüpheli - programınız pytest tarafından çağrılmışsa? veya pydoc koşucusu mu? veya uwsgi tarafından çağrılmışsa?
ve - komut dosyası adını almak için üçüncü bir yöntem var, cevaplarda görmedim - Yığını inceleyebilirsiniz.
Başka bir sorun, Siz (veya başka bir program) sys.argv
ve__main__.__file__
- mevcut olabilir, olmayabilir. Geçerli olabilir ya da olmayabilir. En azından Betiğin (istenen sonuç) var olup olmadığını kontrol edebilirsiniz!
github'daki kütüphanem bitranox / lib_programname tam olarak bunu yapar:
__main__
mevcut olup olmadığını kontrol et__main__.__file__
mevcut olup olmadığını kontrol et__main__.__file__
geçerli bir sonuç veriyor mu (bu komut dosyası var mı?)Bu arada, bu benim çözüm şimdiye kadar çalışıyor setup.py test
, uwsgi
, pytest
, pycharm pytest
, pycharm docrunner (doctest)
, dreampie
,eclipse
Hamur Hellman'ın "Python'dan Bir Sürecin Adının Belirlenmesi" konulu güzel bir blog makalesi de var
Hızlı kirli çözümüm:
__file__.split('/')[-1:][0]
os.path
Dosya adlarını bölmek için daha iyi kullanım
os.path.abspath(__file__)
size mutlak bir yol verecektir ( relpath()
mevcut).
sys.argv[-1]
size göreceli bir yol verecektir.
Python 3.5'ten itibaren şunları yapabilirsiniz:
from pathlib import Path
Path(__file__).stem
Buradan daha fazlasını görün: https://docs.python.org/3.5/library/pathlib.html#pathlib.PurePath.stem
Örneğin, kullanıcı dizinim altında test.py
bununla adlandırılmış bir dosya var:
from pathlib import Path
print(Path(__file__).stem)
print(__file__)
bu çıktıları çalıştırmak:
>>> python3.6 test.py
test
test.py
Exception NameError: NameError("global name '__file__' is not defined",)
"