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.

Jawaban:


161

Berkat mcandre, jawabannya adalah:

#python3
from inspect import currentframe, getframeinfo

frameinfo = getframeinfo(currentframe())

print(frameinfo.filename, frameinfo.lineno)

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

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

11

Nama file :

__file__
# or
sys.argv[0]

Garis :

inspect.currentframe().f_lineno

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


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

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


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.


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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.