首先,如果我们讨论注入匿名代码的方式,这里有几个缺失的用例。
code.compile_command()
code.interact()
imp.load_compiled()
imp.load_dynamic()
imp.load_module()
__builtin__.compile()
loading C compiled shared objects? example: _socket?)
但是,真正的问题是,你的目标是什么 - 你是在试图强制实施某种安全性吗? 还是你只是对正在加载的内容感兴趣。
如果你对安全性感兴趣,通过exec / execfile导入的文件名并不重要 - 你应该使用rexec,它提供了以下功能:
该模块包含RExec类,支持r_eval(),r_execfile(),r_exec()和r_import()方法,这些方法是标准Python函数eval(),execfile()和exec和import语句的受限版本。在此受限环境中执行的代码将仅访问被视为安全的模块和函数; 您可以子类化RExec添加或删除所需的功能。
然而,如果这更多是一个学术追求..这里有一些愚蠢的方法,你可能能够深入挖掘..
示例脚本:
./deep.py
print ' >> level 1'
execfile('deeper.py')
print ' << level 1'
./deeper.py
print '\t >> level 2'
exec("import sys; sys.path.append('/tmp'); import deepest")
print '\t << level 2'
/tmp/deepest.py
print '\t\t >> level 3'
print '\t\t\t I can see the earths core.'
print '\t\t << level 3'
./codespy.py
import sys, os
def overseer(frame, event, arg):
print "loaded(%s)" % os.path.abspath(frame.f_code.co_filename)
sys.settrace(overseer)
execfile("deep.py")
sys.exit(0)
输出
loaded(/Users/synthesizerpatel/deep.py)
>> level 1
loaded(/Users/synthesizerpatel/deeper.py)
>> level 2
loaded(/Users/synthesizerpatel/<string>)
loaded(/tmp/deepest.py)
>> level 3
I can see the earths core.
<< level 3
<< level 2
<< level 1
当然,这是一种资源密集型的方法,你将追踪所有的代码... 不是很高效。但是,我认为这是一种新颖的方法,因为即使你深入嵌套,它仍然可以继续工作。你不能覆盖 'eval'。虽然你可以覆盖 execfile()。
请注意,这种方法只涵盖了exec/execfile,而不是'import'。对于更高级别的'module'加载钩子,您可能可以使用
sys.path_hooks(PyMOTW的说明)。
这就是我能想到的全部。
pathlib
解决方案:https://dev59.com/QXA65IYBdhLWcg3wogEb#48931294 - Danpython myfile.py
是可以的,但是在 vim 中运行:!python %
和:!python myfile.py
都会失败并显示“系统找不到指定的路径”。这非常令人烦恼。有没有人能够评论一下背后的原因以及可能的解决方法? - inVader