在Python中访问父命名空间
def c():
def a():
print dir()
def b():
pass
a()
c()
可能是一个非常简单的问题,但我似乎无法通过Google搜索找到答案。我有上面的代码,我想要一个方法来打印包含方法a和b的命名空间,即我希望它打印它被调用的点形式的命名空间。这可能吗?最好在Python 2.x的在Python中访问父命名空间
您可以使用inspect
模块从标准Python库:
import inspect
def c():
def a():
frame = inspect.currentframe()
print frame.f_back.f_locals
def b():
pass
a()
c()
但frames
使用后应删除,见note。
对评论的回应。
可能的办法限制检查功能,对于学生:
import sys
sys.modules['inspect'] = None
sys._getframe = None
坏主意。这是昂贵的和肮脏的 – 2012-02-03 14:58:05
其实,这正是我所害怕的可能性:学生可以使用检查来打印我们用来测试他们的练习的功能的来源。谢谢。现在我有一个可能的攻击,这是由我来找到一种方法来防止它 – nvcleemp 2012-02-03 15:04:15
@ nvcleemp,我认为可以限制'inspect'和'sys._getframe'的使用。 – reclosedev 2012-02-03 15:14:31
我会去与locals()这样的:
def c():
def a(locals_):
print locals_
def b():
pass
a(locals())
c()
是的,这是行得通的,但我不能改变函数的签名a,我不能改变从哪个点它被称为。 (基本上,我试图找到我的学生可以使用哪些攻击来发现我们的在线测试应用程序中如何检查解决方案) – nvcleemp 2012-02-03 14:57:01
为什么您将学生代码与一些代码混合/插入?看起来很奇怪。为什么不能像模块一样导入并定期调用函数。或者eval,听起来更简单。或者,使用RestrictedPython来确保安全。 – Ski 2012-02-03 15:11:37
我们使用现有的网站(spoj.pl),但已经撰写了一些自定义评委来为我们的学生提供更多反馈。其中一名评委拿着学生代码,运行它,然后运行doctest,并给学生提供这个doctest的结果。看起来我有点过早了:我认为他们可以使用inspect.getsource,但是由于被执行的代码是生成的,因此似乎无法以这种方式获得源代码。 – nvcleemp 2012-02-03 15:19:10
我会尝试全局()在Python 3有另一种方式做到这一点,以及 – 2012-02-03 14:50:56
你为什么要这么做? – 2012-02-03 14:58:20
我已经在两个答案的评论中解释过:基本上我正在为我们的学生在我们的在线测试应用程序中寻找漏洞。看起来是正确的,我们需要阻止学生对测试代码进行反向工程以找到解决方案。 (当然,任何聪明的学生也应该有足够的技能来通过练习) – nvcleemp 2012-02-03 15:09:26