ชื่อไฟล์และหมายเลขบรรทัดของสคริปต์ python


114

ฉันจะรับชื่อไฟล์และหมายเลขบรรทัดในสคริปต์ python ได้อย่างไร

ข้อมูลไฟล์ที่เราได้รับจากการย้อนกลับข้อยกเว้น ในกรณีนี้โดยไม่มีข้อยกเว้น

คำตอบ:


162

ขอบคุณ mcandre คำตอบคือ:

#python3
from inspect import currentframe, getframeinfo

frameinfo = getframeinfo(currentframe())

print(frameinfo.filename, frameinfo.lineno)

1
การใช้วิธีนี้มีผลกระทบต่อประสิทธิภาพหรือไม่ (เช่นเพิ่มเวลาทำงานเล็กน้อยหรือต้องการ CPU มากขึ้น)
gsinha

6
@gsinha: ทุกการเรียกใช้ฟังก์ชันมีผลต่อประสิทธิภาพ คุณต้องวัดว่าผลกระทบนี้เป็นที่ยอมรับสำหรับคุณหรือไม่
omikron

5
ดังนั้นหากคุณชอบคำตอบประเภท "หนึ่งบรรทัด" ให้ใช้:import inspect inspect.getframeinfo(inspect.currentframe()).lineno
1-ijk

1
@LimokPalantaemon จะเกิดขึ้นเมื่อcurrentframe()ถูกเรียกซึ่งหมายความว่าคุณไม่สามารถทำให้สิ่งนี้ง่ายขึ้นได้อีกgetframeinfo(currentframe()).lineno(หากคุณสนใจเฉพาะหมายเลขบรรทัดไม่ใช่ชื่อไฟล์) ดูdocs.python.org/2/library/inspect.html#inspect.currentframe
Aaron Miller

1
@joey ไม่ควรมีวงเล็บในคำสั่งพิมพ์หรือไม่?
MCG

49

การใช้งานนั้นcurrentframe().f_backขึ้นอยู่กับว่าคุณกำลังใช้ฟังก์ชันหรือไม่

โทรตรวจสอบโดยตรง:

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

เรียกใช้ฟังก์ชันที่ทำเพื่อคุณ:

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
บวกหนึ่งสำหรับการจัดหาโซลูชันในฟังก์ชันที่เรียกได้ ดีมาก!
MikeyE

21

มีประโยชน์หากใช้ในไฟล์ทั่วไป - พิมพ์ชื่อไฟล์หมายเลขบรรทัดและฟังก์ชันของผู้โทร:

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

11

ชื่อไฟล์ :

__file__
# or
sys.argv[0]

บรรทัด :

inspect.currentframe().f_lineno

(ไม่ได้inspect.currentframe().f_back.f_linenoระบุไว้ข้างต้น)


NameError: global name '__file__' is not definedบนล่าม Python ของฉัน: Python 2.7.6 (default, Sep 26 2014, 15:59:23). ดูstackoverflow.com/questions/9271464/…
bgoodr

10

ควรใช้ sys ด้วย -

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

ผลลัพธ์คือ:

['__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

เพียงเพื่อมีส่วนร่วม

มีlinecacheโมดูลใน python นี่คือสองลิงค์ที่สามารถช่วยได้

เอกสารโมดูล
linecache ซอร์สโค้ด linecache

ในแง่หนึ่งคุณสามารถ "ถ่ายโอนข้อมูล" ไฟล์ทั้งหมดลงในแคชและอ่านด้วยข้อมูล linecache.cache จากคลาส

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

สำหรับข้อมูลเพิ่มเติมสำหรับการจัดการข้อผิดพลาดคุณสามารถใช้

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


3

ใน Python 3 คุณสามารถใช้รูปแบบบน:

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

ในรหัสคุณสามารถใช้:

Deb("Some useful information")
Deb()

ผลิต:

123: Some useful information
124:

โดยที่ 123 และ 124 คือสายที่โทรออก


0

นี่คือสิ่งที่ใช้ได้ผลสำหรับฉันในการรับหมายเลขบรรทัดใน Python 3.7.3 ใน VSCode 1.39.2 ( dmsgเป็นหน่วยความจำของฉันสำหรับข้อความดีบัก):

import inspect

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

ในการเรียกแสดงตัวแปรname_sและค่าของตัวแปร:

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

ผลลัพธ์มีลักษณะดังนี้:

37| name_s: value_of_variable_at_line_37
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.