2016-09-21 7 views
1

Итак, в качестве шутки я написал версию goto для python, которую я хотел использовать в качестве библиотеки. Функция, которую я написал для нее, выглядит следующим образом.Есть ли версия __file__, которая при использовании в функции получит имя файла, который использует библиотеку?

def goto(loc): 
    exec(open(__file__).read().split("# "+str(loc))[1],globals()) 
    quit() 

Это работает в случаях, когда он находится в файле, где используется Гото, например, как это:

def goto(loc): 
    exec(open(__file__).read().split("# "+str(loc))[1],globals()) 
    quit() 


# hi 
print("test") 
goto("hi") 

Однако, если я импортировать Гото в другой файл, он не работает, как

__file__ 

всегда будет возвращать файл с функцией в нем, а не с той, в которой он используется. Есть ли эквивалент файла, который позволит мне импортировать файл с функцией goto в нем и заставить его работать?

+0

Не удалось побеспокоить ответ, но да - вам нужно копаться в стеке вызовов , начните искать в 'inspect.currentframe(). f_back' – wim

ответ

0

Да, вы можете, если вы проверить стек вызовов:

import inspect 

def goto(): 
    try: 
     frame = inspect.currentframe() 
     print(frame.f_back.f_globals['__file__']) 
    finally: 
     # break reference cycles 
     # https://docs.python.org/3.6/library/inspect.html#the-interpreter-stack 
     del frame 

goto() 

Обратите внимание, что стек вызовов на самом деле реализация питон зависит - Так что для некоторых питона переводчиков, это может на самом деле не работает ...

Конечно, я также показал вам, как получить глобальные звонки (locals можно найти через frame.f_back.f_locals для всех ваших потребностей exec).

Также обратите внимание, что it looks like you can implement a jump command, написав на фрейме f_lineno - что может быть лучшим способом реализовать ваш goto. Я никогда этого не делал, поэтому не могу на самом деле советовать вам, как на самом деле его кодировать :-)