全局命名空间中的funcs与vars

昨天没有得到答案,我已经做了一些调查,我 显然不了解Python名称空间的工作方式. 这是一个测试 程序: #!/usr/bin/python b = 2 def sumwithglobal(a): 返回A + B #这很简单 打印"案例1:正常功能电话:" 打印sumwithglobal(2) 打印 #如果您不发送eval的全球范围,则使用 #呼叫程序,因此基本上与情况1相同 打印'案例2:使用相同的Globals()从评估内部进行函数调用:' 打印评估(" sumwithglobal(2)") 打印 #由于我要发送的全球范围,但尚未包含定义 #对于sumwithglobal(),显然这将失败(注释出来 #past误差) 打印'案例3:尝试仅替换全局var b(已知已知失败 原因)' #print eval(" sumwithglobal(2)",{'b':3}) 打印 #这里是定义sumwithglobals,但不可以b,但仍然有效. 为什么? #我不应该遇到B不确定的错误,因为它不在 #globals the评估? 打印'案例4:尝试仅设置函数sumwithglobal(成功 出于未知原因' 打印评估(" sumwithglobal(2)",{'sumwithglobal':sumwithglobal}) 打印 #最后我定义了这两个 #again,为什么? 在评估的全局中,b = 3,不是吗? 打印'案例5:尝试同时设置功能和var. (var的价值错误)'' 打印评估(" sumwithglobal(2)",{'sumwithglobal':sumwithglobal,'b':3}) 打印 如果我在sumwithglobal中添加" print globals()",我会在其中看到{'b':2} 案例1、2、4和5.我在做什么错?

# 回答1

David Rysdam 写道: ... 您正在误解Python Globals:它们是人均,而不是" 所有模块". Alex
# 回答2

亚历克斯·马特利(Alex Martelli)写道:... 内部的函数sumwithglobal使用了所定义的模块的全局字典,而不是其所调用的模块的全局字典,包括您在eRET中拥有的" Kinda solda solda pseudo"模块. 这也解释了: 您正在误解Python Globals:它们是人均,而不是"所有模块". 亚历克斯 好的,我可以理解这一点. 我不确定有什么意义 那时能够为eval()指定全球范围,但是如果不这样做 我想要的不做我想要的. 我想做的是能够运行多个使用相同的脚本 全局变量和函数名称,但能够拥有我的主脚本 通过编程定义这些变量和函数. 我可以做到吗 带有rexec沙盒的东西? 或更多地是关于保持 exec()'d执行操作的代码比准确指定它可以做什么?
# 回答3

David Rysdam 写道: ... 当您传递给评估是一个表达式时,这一点更清晰: eval('a+b',dict(a = 23,b = 99)). 我想做的是能够运行多个使用相同的全局变量和函数名称的脚本,但能够使我的主脚本以编程方式定义这些变量和函数. 我可不可以做 有rexec沙盒的东西吗? 还是Rexec更多地是关于防止exec()'d代码执行操作,而不是准确指定它可以做什么? REXEC已被删除,因为它没有提供安全性 据称提供(这是关于防止代码做坏事,但是 它确实没有),叹了口气. 例如,您可以通过设置所需的值来完成您想要的事情 您要调用的函数的模块对象 - 该模块对象的对象 字典是该函数的全局名称空间. 说: sub_module = __import __(what_one_this_time) vars(sub_module).update(what_dict_this_time) 打印sub_module.the_function(23) 还有其他方法,但是很少有直接的方式. Alex
# 回答4

亚历克斯·马特利(Alex Martelli)写道: Rexec之所以被删除,是因为它没有提供其声称提供的安全性(这是为了防止代码做坏事,但实际上没有做),叹了口气. 您可以通过在要调用的函数的模块对象中设置所需的值来完成您想要的事情 - 该模块对象的字典是函数的全局名称空间. 说:sub_module = __import __(what_one_this_time)vars(sub_module).update(what_dict_this_time)print sub_module.the_function(23)还有其他方法,但是很少有像这样的直接. 亚历克斯 哦,哇,当然! 我可以在模块本身上设置属性. 我是 必须重新考虑我在做的事情,然后弄乱一会儿,我 当然,稍后我会遇到问题和问题. 谢谢!
# 回答5

David Rysdam 写道: ... ...哦,哇,当然! 我可以在模块本身上设置属性. 我将不得不重新考虑自己在做的事情,然后弄乱这一点,我相信以后我会遇到问题和问题. 谢谢! 别客气! 是的,由于您的模块没有用于其他模块 目的除了运行您要控制的脚本集,更改 在您的情况下,这些模块的全球变量应该足够安全. Alex
# 回答6

亚历克斯·马特利(Alex Martelli)写道:... 别客气! 是的,由于您的模块没有用于其他目的,除了运行您要控制的脚本集,因此在您的情况下更改这些模块的全局变量应该足够安全. 亚历克斯 好,愚蠢的问题#1: 为什么这样做: sub_module = __import __(what_module_this_time) vars(sub_module).update(what_dict_this_time) 当我可以做到这一点时: __import __(what_module_this_time,what_dict_this_time) ?
# 回答7

David Rysdam 写道: ... 您可以做任何您想做的事,但是什么使您认为这些结构 有类似的效果吗? 在__import __中引用Python的在线文档, """ 标准实现根本不使用其当地参数, 并使用其全球群体仅确定 导入语句 """ 简而言之,__import__的标准实现不会改变 它导入的模块的任何方式. Alex
# 回答8

亚历克斯·马特利(Alex Martelli)写道: 你可以做 您希望,但是什么使您认为这些结构具有相似的效果? 在__import__上引用Python的在线文档,"""标准实现根本不使用其当地参数,并且仅使用其Globals来确定导入语句的包装上下文" 以任何方式更改它导入的模块的dict. 亚历克斯 啊,我明白了. 您的" what_dict_this_time"字典,您如何想象 在职的? 我只是将函数名称字符串映射到函数 ({'logerror':logerror}),但是(长话短说)不起作用 想. 但是我不应该在那里定义该功能 字典本身? 不过,也许这变得太不可思议了,神奇和无可奈何.
# 回答9

David Rysdam写道:您的"哪个_dict_this_time"字典,您如何想象该工作? 我只是将函数名称字符串映射到函数({'logerror':logerror}),但是(长话短说)不起作用. 但是,我不应该在字典本身中定义该功能吗? 也许这会更加清楚,更加敏锐. (的 当然,这是指我正确阅读Alex的意图... :)) std_global_dict = {'logerror':logerror,...} script_module = __import __('some_script_module') vars(script_module).update(std_global_dict) 这将具有注入所有指定名称的效果(在 std_global_dict)进入Scriptlet的模块,可以用作 全局变量. (但是请注意,Logerror()和其他功能 在std_global_dict中,将在它们的上下文中执行 定义 - 也就是说,Logerror正在使用其自己的模块的全球,而不是 Script_Module的Globals或STD_GLOBAL_DICT. 杰夫·香农 技术人员/程序员 信用国际
# 回答10

在周二,2004年9月14日14:25:04 -0400,David Rysdam 写道: 您可以做任何您想做的事,但是什么使您认为这些结构具有相似的效果? 在__import__上引用Python的在线文档,"""标准实现根本不使用其当地参数,并且仅使用其Globals来确定导入语句的包装上下文" 以任何方式更改它导入的模块的dict. Alexah,我看到. 我只是将函数名称字符串映射到函数({'logerror':logerror}),但是(长话短说)不起作用. 但是,我不应该在thedictionary本身中定义该功能吗? 也许这会给您一些想法: 这里是empty.py只是一个带有一个的空白文本行(在这种情况下为windows, 为此,我将在二进制中显示: '\ n' 当然,它不必开始空. 这 点是 exec和execfile不会保存编译的.pyc供您制作 下次会更快,而导入则(除非阻止它 由于缺乏写作特权,我认为). 问候, Bengt Richter
# 回答11

David Rysdam 写道: ... ...您的"哪个_dict_this_time"字典,您如何想象该工作? 就像其他任何词典一样 - 也许我没有您的问题...? 我只是将函数名称字符串映射到函数({'logerror':logerror}),但是(长话短说)不起作用. 但是,我不应该在字典本身中定义该功能吗? ....因为def是一个陈述,并且"在字典本身中",您可以 当然,只有表达...? 这是一个技巧的问题...吗? 不过,也许这变得太不可思议了,神奇和无可奈何. 您的问题绝对对我来说是显而易见的... Alex
# 回答12

班格·里奇特(Bengt Richter)写道:啊,我看到. 我只是将函数名称字符串映射到函数({'logerror':logerror}),但是(长话短说)不起作用. 但是,我不应该在thedictionary本身中定义该功能吗? 也许这会给您一些想法: 啊哈,是的,这确实给了我想法. 非常出色的教程,我 当我以后再混淆自己时,就保存了它. 我想我 知道如何做我现在想做的事,尽管我开始 质疑提供有关功能的智慧. 但是如果 我要,应该是对的,所以我仍然感谢您.
# 回答13

大卫·里斯丹(David Rysdam)写道: 我知道我以错误的方式这样做,我刚刚意识到 正确的方法是:我应该只使用对象而不是尝试操纵 字典. 当我制作新版本的" API"时,我只是创建一个 从上一个版本继承的新类. 我有点担心我花了很长时间才意识到这一点...

标签: python

添加新评论