nome file e numero di riga dello script Python


113

Come posso ottenere il nome del file e il numero di riga nello script Python.

Esattamente le informazioni sul file che otteniamo da un traceback di eccezione. In questo caso senza sollevare un'eccezione.

Risposte:


161

Grazie a mcandre, la risposta è:

#python3
from inspect import currentframe, getframeinfo

frameinfo = getframeinfo(currentframe())

print(frameinfo.filename, frameinfo.lineno)

1
L'utilizzo di questo metodo ha un impatto sulle prestazioni (come un lieve aumento del tempo di esecuzione o più CPU necessaria)?
gsinha

6
@gsinha: ogni chiamata di funzione ha un impatto sulle prestazioni. Devi misurare se questo impatto è accettabile per te.
omikron

5
Quindi, se ti piacciono le risposte di tipo "una riga", usa:import inspect inspect.getframeinfo(inspect.currentframe()).lineno
1-ijk

1
@LimokPalantaemon accade quando currentframe()viene chiamato, il che significa che non puoi semplificarlo più di getframeinfo(currentframe()).lineno(se ti interessa solo il numero di riga e non il nome del file). Vedi docs.python.org/2/library/inspect.html#inspect.currentframe
Aaron Miller,

1
@joey, non dovrebbero esserci parentesi nell'istruzione print?
MCG

49

L'utilizzo currentframe().f_backdipende dall'utilizzo o meno di una funzione.

Chiamando inspect direttamente:

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

Chiamare una funzione che lo fa per te:

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
Più uno, per fornire una soluzione in una funzione richiamabile. Molto bella!
MikeyE

21

Comodo se utilizzato in un file comune: stampa il nome del file, il numero di riga e la funzione del chiamante:

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

11

Nome file :

__file__
# or
sys.argv[0]

Linea :

inspect.currentframe().f_lineno

(non inspect.currentframe().f_back.f_linenocome menzionato sopra)


NameError: global name '__file__' is not definedsul mio interprete Python: Python 2.7.6 (default, Sep 26 2014, 15:59:23). Vedere stackoverflow.com/questions/9271464/...
bgoodr

10

Meglio usare anche sys-

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

L'output è:

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

Solo per contribuire,

c'è un linecachemodulo in python, ecco due link che possono aiutare.

documentazione del modulo
linecache codice sorgente di linecache

In un certo senso, puoi "scaricare" un intero file nella sua cache e leggerlo con i dati linecache.cache dalla classe.

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

Per ulteriori informazioni, per la gestione degli errori, puoi semplicemente usare

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


3

In Python 3 puoi usare una variazione su:

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

Nel codice, puoi quindi utilizzare:

Deb("Some useful information")
Deb()

Produrre:

123: Some useful information
124:

Dove 123 e 124 sono le linee da cui vengono effettuate le chiamate.


0

Ecco cosa funziona per me per ottenere il numero di riga in Python 3.7.3 in VSCode 1.39.2 ( dmsgè il mio mnemonico per il messaggio di debug):

import inspect

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

Per chiamare mostrando una variabile name_se il suo valore:

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

L'output è simile a questo:

37| name_s: value_of_variable_at_line_37
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.