nama file dan nomor baris skrip python

113

Bagaimana saya bisa mendapatkan nama file dan nomor baris dalam skrip python.

Tepatnya informasi file yang kami dapatkan dari pengecualian traceback. Dalam kasus ini tanpa menimbulkan pengecualian.

Joey
sumber

Jawaban:

161

Berkat mcandre, jawabannya adalah:

#python3
from inspect import currentframe, getframeinfo

frameinfo = getframeinfo(currentframe())

print(frameinfo.filename, frameinfo.lineno)
Joey
sumber
1
Apakah menggunakan metode ini berdampak pada kinerja (seperti peningkatan kecil dalam waktu proses atau lebih banyak CPU yang dibutuhkan)?
gsinha
6
@gsinha: Setiap pemanggilan fungsi memiliki dampak kinerja. Anda harus mengukur apakah dampak ini dapat diterima untuk Anda.
omikron
5
Jadi, jika Anda suka tipe jawaban "satu baris", gunakan:import inspect inspect.getframeinfo(inspect.currentframe()).lineno
1-ijk
1
@LimokPalantaemon itu terjadi ketika currentframe()dipanggil, yang berarti Anda tidak dapat menyederhanakan ini lebih dari getframeinfo(currentframe()).lineno(jika Anda hanya peduli tentang nomor baris dan bukan nama file). Lihat docs.python.org/2/library/inspect.html#inspect.currentframe
Aaron Miller
1
@ Joey, bukankah seharusnya ada tanda kurung di pernyataan cetak?
MCG
49

Apakah Anda menggunakan currentframe().f_backtergantung pada apakah Anda menggunakan suatu fungsi atau tidak.

Memanggil inspeksi langsung:

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

Memanggil fungsi yang melakukannya untuk Anda:

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()
aaren
sumber
2
Ditambah satu, untuk memberikan solusi dalam fungsi yang dapat dipanggil. Sangat bagus!
MikeyE
21

Berguna jika digunakan dalam file umum - mencetak nama file, nomor baris dan fungsi pemanggil:

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

Nama file :

__file__
# or
sys.argv[0]

Garis :

inspect.currentframe().f_lineno

(tidak inspect.currentframe().f_back.f_linenoseperti yang disebutkan di atas)

arilou
sumber
NameError: global name '__file__' is not definedpada interpreter Python saya: Python 2.7.6 (default, Sep 26 2014, 15:59:23). Lihat stackoverflow.com/questions/9271464/…
bgoodr
10

Lebih baik menggunakan sys juga-

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

Outputnya adalah:

['__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
Mohammad Shahid Siddiqui
sumber
6

Hanya untuk berkontribusi,

ada linecachemodul di python, berikut adalah dua tautan yang dapat membantu.

dokumentasi modul
linecache kode sumber linecache

Dalam arti tertentu, Anda dapat "membuang" seluruh file ke dalam cache, dan membacanya dengan data linecache.cache dari kelas.

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

Untuk info tambahan, untuk penanganan error, Anda cukup menggunakan

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

file_name = __FILE__
current_line_no = inspect.stack()[0][2]
current_function_name = inspect.stack()[0][3]

#Try printing inspect.stack() you can see current stack and pick whatever you want 
Haroon Rashedu
sumber
Mirip dengan __file__: Lihat stackoverflow.com/questions/3056048/…
bgoodr
3

Di Python 3 Anda dapat menggunakan variasi pada:

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

Dalam kode, Anda kemudian dapat menggunakan:

Deb("Some useful information")
Deb()

Untuk menghasilkan:

123: Some useful information
124:

Di mana 123 dan 124 adalah saluran yang digunakan untuk membuat panggilan.

Thickycat
sumber
0

Inilah yang berhasil bagi saya untuk mendapatkan nomor baris dengan Python 3.7.3 di VSCode 1.39.2 ( dmsgadalah mnemonik saya untuk pesan debug):

import inspect

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

Untuk memanggil menampilkan variabel name_sdan nilainya:

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

Outputnya terlihat seperti ini:

37| name_s: value_of_variable_at_line_37
Steph
sumber