Câu trả lời:
Bạn có thể sử dụng __file__để có được tên của tập tin hiện tại. Khi được sử dụng trong mô-đun chính, đây là tên của tập lệnh ban đầu được gọi.
Nếu bạn muốn bỏ qua phần thư mục (có thể có mặt), bạn có thể sử dụng os.path.basename(__file__).
__file__không được định nghĩa trong trình thông dịch tương tác, vì nó vô nghĩa ở đó. Nó được thiết lập bởi việc thực hiện nhập, vì vậy nếu bạn sử dụng cơ chế nhập không chuẩn thì nó cũng có thể không được đặt.
import oscần phải có để nó hoạt động. Tôi sẽ thêm điều này vào câu trả lời.
import osvà import os.pathhoàn toàn tương đương.
import sys
print sys.argv[0]
Điều này sẽ in foo.pycho python foo.py, dir/foo.pycho python dir/foo.py, vv Đó là đối số đầu tiên python. (Lưu ý rằng sau py2exe thì sẽ như vậy foo.exe.)
python linkfile.py, nơi linkfile.pymột symlink đến realfile.py, sys.argv[0]sẽ là 'linkfile.py', có thể hoặc không thể là những gì bạn muốn; nó chắc chắn là những gì tôi mong đợi . __file__là như nhau: nó sẽ được linkfile.py. Nếu bạn muốn tìm 'realfile.py'từ 'linkfile.py', hãy thử os.path.realpath('linkfile.py').
__file__thay thế.
Để hoàn thiện, tôi nghĩ rằng sẽ rất đáng để tóm tắt các kết quả có thể khác nhau và cung cấp tài liệu tham khảo cho hành vi chính xác của từng:
__file__là tập tin hiện đang thực thi, như chi tiết trong tài liệu chính thức :
__file__là tên đường dẫn của tệp mà mô-đun được tải, nếu nó được tải từ một tệp. Các__file__thuộc tính có thể thiếu cho một số loại mô-đun, chẳng hạn như C module được liên kết tĩnh thành người phiên dịch; đối với các mô-đun mở rộng được tải động từ thư viện dùng chung, đó là tên đường dẫn của tệp thư viện dùng chung.
Từ Python3.4 trở đi, mỗi vấn đề 18416 , __file__luôn là một đường dẫn tuyệt đối, trừ khi tệp hiện đang thực thi là một tập lệnh được thực thi trực tiếp (không thông qua trình thông dịch với -mtùy chọn dòng lệnh) bằng cách sử dụng đường dẫn tương đối.
__main__.__file__(yêu cầu nhập __main__) chỉ cần truy cập vào __file__thuộc tính đã nói ở trên của mô-đun chính , ví dụ: tập lệnh được gọi từ dòng lệnh.
sys.argv[0](yêu cầu nhập sys) là tên tập lệnh được gọi từ dòng lệnh và có thể là một đường dẫn tuyệt đối, như được nêu chi tiết trong tài liệu chính thức :
argv[0]là tên tập lệnh (nó phụ thuộc vào hệ điều hành cho dù đây có phải là tên đường dẫn đầy đủ hay không). Nếu lệnh được thực thi bằng-ctùy chọn dòng lệnh cho trình thông dịch,argv[0]được đặt thành chuỗi'-c'. Nếu không có tên tập lệnh nào được chuyển đến trình thông dịch Python, thì đóargv[0]là chuỗi rỗng.
Như đã đề cập trong câu trả lời khác cho câu hỏi này , các tập lệnh Python được chuyển đổi thành các chương trình thực thi độc lập thông qua các công cụ như py2exe hoặc PyInstaller có thể không hiển thị kết quả mong muốn khi sử dụng phương pháp này (nghĩa là sys.argv[0]sẽ giữ tên của tệp thực thi thay vì tên của tệp Python chính trong tệp thực thi đó).
Nếu không có tùy chọn nào nói trên có vẻ hoạt động, có thể do hoạt động nhập không đều, mô-đun kiểm tra có thể hữu ích. Cụ thể, việc gọi inspect.getfile(...)vào inspect.currentframe()có thể hoạt động, mặc dù cái sau sẽ trở lạiNone khi chạy trong một triển khai không có khung ngăn xếp Python .
Nếu tập lệnh hiện tại là một liên kết tượng trưng, thì tất cả các đoạn trên sẽ trả về đường dẫn của liên kết tượng trưng thay vì đường dẫn của tệp thực và os.path.realpath(...)nên được gọi để trích xuất đoạn sau.
os.path.basename(...)có thể được gọi trên bất kỳ mục nào ở trên để trích xuất tên tệp thực tế và os.path.splitext(...)có thể được gọi trên tên tệp thực tế để cắt bớt hậu tố của nó, như trongos.path.splitext(os.path.basename(...)) .
Từ Python 3.4 trở đi, trên mỗi PEP 428 , PurePathlớp của pathlibmô-đun cũng có thể được sử dụng cho bất kỳ mục nào ở trên. Cụ thể, pathlib.PurePath(...).nametrích xuất tên tệp thực tế và pathlib.PurePath(...).stemtrích xuất tên tệp thực tế mà không có hậu tố của nó.
Lưu ý rằng __file__sẽ cung cấp cho tệp nơi mã này cư trú, có thể được nhập và khác với tệp chính đang được diễn giải. Để lấy tệp chính, mô-đun __main__ đặc biệt có thể được sử dụng:
import __main__ as main
print(main.__file__)
Lưu ý rằng nó __main__.__file__hoạt động trong Python 2.7 nhưng không phải trong 3.2, vì vậy hãy sử dụng cú pháp nhập như dưới đây để làm cho nó di động.
rPythongói từ Rngôn ngữ. Đó phải là một trường hợp đặc biệt mà quá khó để xử lý.
__main__nội bộ, để sử dụng trong việc chuyển các biến giữa Rvà pythonvì vậy sẽ tương đối dễ dàng để đặt nó __main__.__file__trước khi gọi bất cứ thứ gì khác, nhưng tôi thậm chí không chắc giá trị nào phù hợp trong trường hợp này.
Các câu trả lời trên là tốt. Nhưng tôi thấy phương pháp này hiệu quả hơn bằng cách sử dụng các kết quả trên.
Điều này dẫn đến tên tập tin thực tế không phải là một đường dẫn.
import sys
import os
file_name = os.path.basename(sys.argv[0])
Đối với các phiên bản Python hiện đại (3,4+), Path(__file__).namenên có nhiều thành ngữ hơn. Ngoài ra, Path(__file__).stemcung cấp cho bạn tên tập lệnh mà không cần .pyphần mở rộng.
from pathlib import Pathđầu tiên.
pathlibđược giới thiệu trong Python 3.4, vì vậy nó sẽ hoạt động bắt đầu từ Python 3.4.
Giả sử tên tệp là foo.py, đoạn dưới đây
import sys
print sys.argv[0][:-3]
hoặc là
import sys
print sys.argv[0][::-1][3:][::-1]
Đối với các phạm vi khác có nhiều ký tự hơn, ví dụ như tên tệp foo.pypy
import sys
print sys.argv[0].split('.')[0]
Nếu bạn muốn trích xuất từ một đường dẫn tuyệt đối
import sys
print sys.argv[0].split('/')[-1].split('.')[0]
sẽ xuất foo
Đối số đầu tiên trong sys sẽ là tên tệp hiện tại để nó hoạt động
import sys
print sys.argv[0] # will print the file name
Nếu bạn đang thực hiện nhập bất thường (ví dụ: đó là tệp tùy chọn), hãy thử:
import inspect
print (inspect.getfile(inspect.currentframe()))
Lưu ý rằng điều này sẽ trả về đường dẫn tuyệt đối đến tập tin.
chúng ta có thể thử điều này để có được tên tập lệnh hiện tại mà không cần gia hạn.
import os
script_name = os.path.splitext(os.path.basename(__file__))[0]
tất cả những câu trả lời là tuyệt vời, nhưng có một số vấn đề Bạn có thể không nhìn thấy ngay từ cái nhìn đầu tiên.
cho phép xác định những gì chúng ta muốn - chúng ta muốn tên của tập lệnh đã được thực thi, không phải tên của mô-đun hiện tại - vì vậy __file__sẽ chỉ hoạt động nếu nó được sử dụng trong tập lệnh đã thực hiện, không phải trong mô-đun đã nhập.
sys.argvcũng có vấn đề - nếu chương trình của bạn được gọi bởi pytest thì sao? hay người chạy pydoc? hoặc nếu nó được gọi bởi uwsgi?
và - có một phương pháp thứ ba để có được tên tập lệnh, tôi chưa thấy trong các câu trả lời - Bạn có thể kiểm tra ngăn xếp.
Một vấn đề khác là, Bạn (hoặc một số chương trình khác) có thể can thiệp xung quanh sys.argvvà__main__.__file__ - nó có thể có mặt, nó có thể không. Nó có thể hợp lệ, hoặc không. Ít nhất Bạn có thể kiểm tra xem tập lệnh (kết quả mong muốn) có tồn tại không!
thư viện của tôi bitranox / lib_programname tại github thực hiện chính xác điều đó:
__main__có__main__.__file__có__main__.__file__kết quả hợp lệ (tập lệnh đó có tồn tại không?)bằng cách đó, giải pháp của tôi đang làm việc cho đến nay với setup.py test, uwsgi, pytest, pycharm pytest, pycharm docrunner (doctest), dreampie,eclipse
cũng có một bài viết blog hay về vấn đề đó từ Dough Hellman, "Xác định tên của một quá trình từ Python"
Giải pháp bẩn nhanh của tôi:
__file__.split('/')[-1:][0]
os.pathđể phân chia tên tệp
os.path.abspath(__file__)sẽ cung cấp cho bạn một đường dẫn tuyệt đối (cũng relpath()có sẵn).
sys.argv[-1] sẽ cho bạn một con đường tương đối.
Kể từ Python 3.5, bạn chỉ cần làm:
from pathlib import Path
Path(__file__).stem
Xem thêm tại đây: https://docs.python.org/3.5/l Library / pathlib.html # pathlib.PurePath.stem
Ví dụ: tôi có một tệp trong thư mục người dùng của mình có tên test.pybên trong:
from pathlib import Path
print(Path(__file__).stem)
print(__file__)
chạy kết quả này:
>>> python3.6 test.py
test
test.py
Exception NameError: NameError("global name '__file__' is not defined",)"