tên tệp và số dòng của tập lệnh python


113

Làm cách nào để lấy tên tệp và số dòng trong tập lệnh python.

Chính xác thông tin tệp chúng tôi nhận được từ một truy nguyên ngoại lệ. Trong trường hợp này mà không nêu ra một ngoại lệ.

Câu trả lời:


161

Cảm ơn mcandre, câu trả lời là:

#python3
from inspect import currentframe, getframeinfo

frameinfo = getframeinfo(currentframe())

print(frameinfo.filename, frameinfo.lineno)

1
Sử dụng phương pháp này có bất kỳ tác động nào đến hiệu suất không (như tăng nhẹ thời gian chạy hoặc cần nhiều CPU hơn)?
gsinha

6
@gsinha: Mọi lệnh gọi hàm đều có tác động đến hiệu suất. Bạn phải đo lường xem tác động này có thể chấp nhận được đối với bạn hay không.
omikron

5
Vì vậy, nếu bạn thích "một dòng" loại câu trả lời sử dụng:import inspect inspect.getframeinfo(inspect.currentframe()).lineno
1-IJK

1
@LimokPalantaemon nó xảy ra khi currentframe()được gọi, có nghĩa là bạn không thể đơn giản hóa điều này hơn nữa getframeinfo(currentframe()).lineno(nếu bạn chỉ quan tâm đến số dòng chứ không phải tên tệp). Xem docs.python.org/2/library/inspect.html#inspect.currentframe
Aaron Miller

1
@joey, không nên có dấu ngoặc đơn trong câu lệnh in sao?
MCG

49

Việc bạn sử dụng currentframe().f_backtùy thuộc vào việc bạn có đang sử dụng một chức năng hay không.

Gọi điện kiểm tra trực tiếp:

from inspect import currentframe, getframeinfo

cf = currentframe()
filename = getframeinfo(cf).filename

print "This is line 5, python says line ", cf.f_lineno 
print "The filename is ", filename

Gọi một hàm thực hiện điều đó cho bạn:

from inspect import currentframe

def get_linenumber():
    cf = currentframe()
    return cf.f_back.f_lineno

print "This is line 7, python says line ", get_linenumber()

2
Thêm một, để cung cấp giải pháp trong một hàm có thể gọi. Rất đẹp!
MikeyE

21

Tiện dụng nếu được sử dụng trong một tệp chung - in tên tệp, số dòng và chức năng của trình gọi:

import inspect
def getLineInfo():
    print(inspect.stack()[1][1],":",inspect.stack()[1][2],":",
          inspect.stack()[1][3])

11

Tên tệp :

__file__
# or
sys.argv[0]

Dòng :

inspect.currentframe().f_lineno

(không inspect.currentframe().f_back.f_linenonhư đã đề cập ở trên)


NameError: global name '__file__' is not definedtrên thông dịch Python của tôi: Python 2.7.6 (default, Sep 26 2014, 15:59:23). Xem stackoverflow.com/questions/9271464/…
bgoodr

10

Tốt hơn nên sử dụng sys-

print dir(sys._getframe())
print dir(sys._getframe().f_lineno)
print sys._getframe().f_lineno

Đầu ra là:

['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'f_back', 'f_builtins', 'f_code', 'f_exc_traceback', 'f_exc_type', 'f_exc_value', 'f_globals', 'f_lasti', 'f_lineno', 'f_locals', 'f_restricted', 'f_trace']
['__abs__', '__add__', '__and__', '__class__', '__cmp__', '__coerce__', '__delattr__', '__div__', '__divmod__', '__doc__', '__float__', '__floordiv__', '__format__', '__getattribute__', '__getnewargs__', '__hash__', '__hex__', '__index__', '__init__', '__int__', '__invert__', '__long__', '__lshift__', '__mod__', '__mul__', '__neg__', '__new__', '__nonzero__', '__oct__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdiv__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__', 'bit_length', 'conjugate', 'denominator', 'imag', 'numerator', 'real']
14

6

Chỉ để đóng góp,

có một linecachemô-đun trong python, đây là hai liên kết có thể trợ giúp.

tài liệu mô-đun
linecache mã nguồn linecache

Theo một nghĩa nào đó, bạn có thể "kết xuất" toàn bộ tệp vào bộ nhớ cache của nó và đọc nó với dữ liệu linecache.cache từ lớp.

import linecache as allLines
## have in mind that fileName in linecache behaves as any other open statement, you will need a path to a file if file is not in the same directory as script
linesList = allLines.updatechache( fileName ,None)
for i,x in enumerate(lineslist): print(i,x) #prints the line number and content
#or for more info
print(line.cache)
#or you need a specific line
specLine = allLines.getline(fileName,numbOfLine)
#returns a textual line from that number of line

Để biết thêm thông tin, để xử lý lỗi, bạn chỉ cần sử dụng

from sys import exc_info
try:
     raise YourError # or some other error
except Exception:
     print(exc_info() )


3

Trong Python 3, bạn có thể sử dụng một biến thể trên:

def Deb(msg = None):
  print(f"Debug {sys._getframe().f_back.f_lineno}: {msg if msg is not None else ''}")

Trong mã, bạn có thể sử dụng:

Deb("Some useful information")
Deb()

Để sản xuất:

123: Some useful information
124:

Trong đó 123 và 124 là các dòng mà các cuộc gọi được thực hiện.


0

Đây là những gì hoạt động để tôi lấy số dòng trong Python 3.7.3 trong VSCode 1.39.2 ( dmsglà cách ghi nhớ của tôi cho thông báo gỡ lỗi):

import inspect

def dmsg(text_s):
    print (str(inspect.currentframe().f_back.f_lineno) + '| ' + text_s)

Để gọi hiển thị một biến name_svà giá trị của nó:

name_s = put_code_here
dmsg('name_s: ' + name_s)

Đầu ra giống như sau:

37| name_s: value_of_variable_at_line_37
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.