nom de fichier et numéro de ligne du script python

113

Comment puis-je obtenir le nom du fichier et le numéro de ligne dans un script python.

Exactement les informations de fichier que nous obtenons à partir d'un suivi d'exception. Dans ce cas sans soulever d'exception.

Joey
la source

Réponses:

161

Grâce à mcandre, la réponse est:

#python3
from inspect import currentframe, getframeinfo

frameinfo = getframeinfo(currentframe())

print(frameinfo.filename, frameinfo.lineno)
Joey
la source
1
L'utilisation de cette méthode a-t-elle un impact sur les performances (comme une augmentation mineure du temps d'exécution ou plus de CPU nécessaire)?
gsinha
6
@gsinha: chaque appel de fonction a un impact sur les performances. Vous devez mesurer si cet impact est acceptable pour vous.
omikron
5
Donc, si vous aimez les réponses de type "une ligne", utilisez:import inspect inspect.getframeinfo(inspect.currentframe()).lineno
1-ijk
1
@LimokPalantaemon cela arrive quand il currentframe()est appelé, ce qui signifie que vous ne pouvez plus simplifier cela getframeinfo(currentframe()).lineno(si vous ne vous souciez que du numéro de ligne et non du nom du fichier). Voir docs.python.org/2/library/inspect.html#inspect.currentframe
Aaron Miller
1
@joey, ne devrait-il pas y avoir de parenthèses dans l'instruction d'impression?
MCG
49

Le fait currentframe().f_backque vous l'utilisiez dépend de l' utilisation ou non d'une fonction.

Appelez directement inspect:

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

Appeler une fonction qui le fait pour vous:

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
la source
2
Plus un, pour fournir une solution dans une fonction appelable. Très agréable!
MikeyE
21

Pratique si utilisé dans un fichier commun - imprime le nom du fichier, le numéro de ligne et la fonction de l'appelant:

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

Nom de fichier :

__file__
# or
sys.argv[0]

Ligne :

inspect.currentframe().f_lineno

(pas inspect.currentframe().f_back.f_linenocomme mentionné ci-dessus)

Arilou
la source
NameError: global name '__file__' is not definedsur mon interpréteur Python: Python 2.7.6 (default, Sep 26 2014, 15:59:23). Voir stackoverflow.com/questions/9271464/…
bgoodr
10

Mieux vaut aussi utiliser sys-

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

La sortie est:

['__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
la source
6

Juste pour contribuer,

il y a un linecachemodule en python, voici deux liens qui peuvent aider.

documentation du module
linecache code source linecache

Dans un sens, vous pouvez "vider" un fichier entier dans son cache et le lire avec les données linecache.cache de la 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

Pour plus d'informations, pour la gestion des erreurs, vous pouvez simplement utiliser

from sys import exc_info
try:
     raise YourError # or some other error
except Exception:
     print(exc_info() )
Danilo
la source
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
la source
Similaire à __file__: Voir stackoverflow.com/questions/3056048/…
bgoodr
3

Dans Python 3, vous pouvez utiliser une variante sur:

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

Dans le code, vous pouvez alors utiliser:

Deb("Some useful information")
Deb()

Produire:

123: Some useful information
124:

Où les 123 et 124 sont les lignes à partir desquelles les appels sont effectués.

Thickycat
la source
0

Voici ce qui fonctionne pour moi pour obtenir le numéro de ligne en Python 3.7.3 dans VSCode 1.39.2 ( dmsgest mon mnémonique pour le message de débogage):

import inspect

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

Pour appeler en affichant une variable name_set sa valeur:

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

La sortie ressemble à ceci:

37| name_s: value_of_variable_at_line_37
Steph
la source