“库”方法的范围
我显然在对Python范围的理解很差的情况下工作。也许你可以帮忙。“库”方法的范围
背景:
我使用
if __name__ == "__main__"
结构来我模块(S)在执行 “自检”。每次自测都会调用各种公共方法,并在开发模块时打印结果以进行视觉检查。
为了保持 “普尔蒂” 和可管理的,我创建了一个小方法来简化方法的调用测试:
def pprint_vars(var_in):
print("%s = '%s'" % (var_in, eval(var_in)))
当
foo = "bar"
与调用pprint_vars:
pprint_vars('foo')
打印:
foo = 'bar'
一切都很好。
问题陈述:
不开心,只是吻,我有脑小雨动我的方便,花花公子“pprint_vars”的方法到一个名为“debug_tools.py”一个单独的文件,只需输入“debug_tools”每当我想访问'pprint_vars'。
这里是事情崩溃的地方。我希望
import debug_tools
foo = bar
debug_tools.pprint_vars('foo')
继续工作它的魔力和打印:
foo = 'bar'
相反,它招呼我:
NameError: name 'some_var' is not defined
非理性的信念:
我相信(显然是错误的)该导入会将输入方法(或多或少)与代码“内联”,因此变量范围规则将保持类似于如果方法我们重新定义内联。
请求帮助:
有人可以纠正我对误区的理解吗?
感谢, JS
在Python中的每个文件是它自己的命名空间。一个函数被调用时,解析它的变量以下列顺序:
- 局部变量(包括捕获的变量或在封闭)
- (模块)的全局变量
- 建宏
您可以使用(解释器特定的)inspect
模块作为框架列表导航调用堆栈。由于框架知道它的当地人,全局,建宏和父框架,你可以“看”的解释,通过呼叫方这样的眼(请仅用于调试):
import inspect
def log_var(name):
f = inspect.currentframe().f_back
if name in f.f_locals:
print "local `%s` = %r" % (name, f.f_locals[name])
elif name in f.f_globals:
print "global `%s` = %r" % (name, f.f_globals[name])
elif name in f.f_builtins:
print "builtin `%s` = %r" % (name, f.f_builtins[name])
else:
print "`%s` not found" % name
“全球范围” 实际上并不存在在Python。通常所说的“全球范围”实际上是模块范围。也就是说,在模块级别定义的名称。将该功能放在另一个模块中意味着其模块范围发生变化。
作为实现我的目标的首选方式,您会有什么建议? – 2010-04-07 23:41:47
使用各种'检查。* frame *()'函数获取调用者的框架,然后访问框架的'f_locals'属性以获取本地:'inspect.getouterframes(inspect.currentframe())[1] [0] .f_locals [var_in] ' – 2010-04-07 23:52:59
EVAL接受两个可选参数 - 全球和当地 - 你可以指定为背景来评价你的源:
print("%s = '%s'" % (var_in, eval(var_in, globals())))
如果'var_in'应该位于完全不同的未知模块中,这将无济于事。 – 2010-04-07 23:57:48
我会推荐路过的当地人()的功能,像这样......
def pprint_var(var_name, D):
print "%s = %r" % (var_name, D[var_name])
...
pprint_var(var_name, locals())
,如果你不希望出现这种情况,你可以使用检查模块或sys._getframe做同样的事情,正如其他人所暗示的那样d。
我遇到的基本问题是Python对于简单对象没有名称的意义。对于方法,类等等,对于简单的对象,没有。
因此,在这种特征变量的语言,我的“ppvar”功能会是这个样子(伪代码):
ppvar(var_name):
print("%s = '%s'", var_name, $var_name)
我可以导入该文件包含的任何工程“ppvar”,并把它和它基本上会被“内联”到我的代码中。
唉这很可能是一个“函数式编程”的概念,不适合面向对象的方法。
所有语言都有优缺点。每种语言都有一些“简单”的东西。能够执行如下操作:
print("%s = '%s'" % (var.__name__, var)
在Python中是(至今)不是可行的。好吧。
你确定你发布了完全相同的代码吗?它不应该是'foo ='bar''吗?我找不到错误信息中提到的'some_var'。 – 2010-04-07 23:39:14
你是对的,菲利克斯。我很抱歉。我有(希望)纠正错误。 – 2010-04-07 23:49:06
'__name__'成语通常写成'if __name__' =='__main__“:',测试是否相等。它正好使用了__in__运算符,因为它包含了测试,但有些意外。 – Todd 2010-04-08 02:30:01