[英]How can I access the name a module was imported as?
我想在我的Python模塊foo
編寫一個簡單的教程。
如果模塊作為foo
導入,我希望本教程將其稱為foo
:
>>> import foo
>>> foo.tutorial()
Please run foo.baz().
但是,當模塊導入為bar
,我希望本教程將其稱為bar
:
>>> import foo as bar
>>> bar.tutorial()
Please run bar.baz().
我知道__name__
和__package__
變量都不會在import ... as ...
上更改其值。
與眾不同是否可以在python中檢測模塊的導入方式? -知道導入模塊的第一個別名就足夠了。
它不是很漂亮,萬無一失,也不值得制作,但是:
import inspect
import sys
thismod = sys.modules[__name__]
def imported_as():
imported_frame = inspect.currentframe().f_back.f_back
for k, v in imported_frame.f_locals.items():
if v is thismod:
return k
for k, v in imported_frame.f_globals.items():
if v is thismod:
return k
def tutorial():
print('please call {}.baz()'.format(imported_as()))
一個小小的解釋:
為什么您真的不應該這樣做:
from
進口將打破這一點 inspect.currentframe
超級神奇,通常應在生產代碼中避免使用 這是與安東尼類似的解決方案。 我相信它可以更好地處理多種進口。 from
進口仍然是一個問題。
import inspect
import re
import readline
def tutorial():
frame = inspect.currentframe().f_back
if "__file__" in frame.f_locals:
f = inspect.getframeinfo(frame)
m = re.search(r"(([^\.]*).*)\.tutorial", f.code_context[0].strip())
if m:
parent,path = m.group(2),m.group(1)
if inspect.ismodule(frame.f_locals[parent]):
print "Please run {}.baz()".format(path)
return
print "Verify import and run foo.baz()"
else:
loc = frame.f_locals
glo = frame.f_globals
local_foo = [(k, v.__name__)for k,v in loc.items() if inspect.ismodule(v) and v.__name__=="foo"]
global_foo = [(k, v.__name__)for k,v in glo.items() if inspect.ismodule(v) and v.__name__=="foo"]
if local_foo and set(local_foo)==set(global_foo):
print "Please run {}.baz()".format(global_foo[-1][0])
elif local_foo and global_foo:
print "Please run {}.baz() in local scope or {}.baz()".format(local_foo[-1][0], global_foo[-1][0])
elif local_foo:
print "Please run {}.baz() in local scope".format(local_foo[-1][0])
elif global_foo:
print "Please run {}.baz()".format(global_foo[-1][0])
else:
n = readline.get_current_history_length()
h = [str(readline.get_history_item(i)) for i in range(n)] + [readline.get_line_buffer()]
h.reverse()
for i in h:
matches = re.findall(r"([A-Za-z0-9_-]*(\.[A-Za-z0-9_-]*)*)\.tutorial", i)
for match in matches:
if _baz_check(glo, match[0]):
print "Please run {}.baz()".format(match[0])
return
print "Verify import and run foo.baz()"
def _baz_check(d, path):
path = path.split(".")
if path[0] not in d:
return False
cur = d[path[0]]
for i in range(1,len(path)):
if not hasattr(cur, path[i]):
return False
cur = getattr(cur, path[i])
return hasattr(cur, "__name__") and cur.__name__ == "foo" and hasattr(cur, "baz")
def baz():
print "Baz"
import foo
foo.tutorial()
import foo as bar
bar.tutorial()
def f():
import foo as local_foo
local_foo.tutorial()
f()
from foo import tutorial
tutorial()
import mod
mod.foo.tutorial()
from mod import foo as dum
dum.tutorial()
Please run foo.baz()
Please run bar.baz()
Please run local_foo.baz()
Verify import and run foo.baz()
Please run mod.foo.baz()
Please run dum.baz()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.