Reason for globals() in Python?
在python中使用globals()函数的原因是什么?它只返回全局变量的字典,这些变量已经是全局的,所以它们可以在任何地方使用…我只是好奇地问,想学Python。
1 2 3 4 5 6 7 8 9 10 11 12 13 | def F(): global x x = 1 def G(): print(globals()["x"]) #will return value of global 'x', which is 1 def H(): print(x) #will also return value of global 'x', which, also, is 1 F() G() H() |
我真的看不到这一点?我唯一需要它的时间是,如果我有局部变量和全局变量,它们都有相同的名称。
1 2 3 4 5 6 7 8 9 10 11 | def F(): global x x = 1 def G(): x = 5 print(x) #5 print(globals()["x"]) #1 F() G() |
但是您不应该遇到两个同名的变量的问题,并且需要在同一范围内同时使用这两个变量。
Python为程序员提供了大量的工具来反思运行环境。这只是其中的一个,在一次解析会议上,它可以非常有用地看到全球范围内实际包含的目标。
我敢肯定,理性的背后是与使用EDOCX1〕〔5〕一样的,目的是看到变量在一个函数中定义,或使用
从一个C+++背景来看,我可以理解,这些东西看起来不需要。在一个静态链接中,静态类型的环境中,它们将是绝对的。在这种情况下,在准确的时间编译变量是什么是全球性的,而一个物体的成员将拥有什么,甚至通过另一个编译单元导出什么名称。
在动态语言中,这些东西是不固定的;它们可以根据何种代码被导入而改变,或者甚至在运行时改变。由于这一原因,在一个解调器中获得这一信息的机会是不可估价的。
当你需要用函数字符串命名函数时,它也很有用。For example:
ZZU1
你可以把
因此,这些函数存在于支持其他函数的过程中,这些函数的效益来自于当前环境的不同潜力。例如,你可以叫
如果你想评价一些参照范围内变量的代码,那么这些变量会出现在全球或地方。
为了扩展位,建筑物功能将解释给它的一条Python码。签名是:EDOCX1&3,你可以用它这样:
1 2 3 4 | def foo(): x = 2 y = eval("x + 1", globals(), locals()) print("y=" + y) # should be 3 |
这篇作品,因为解释者从
它还可以用于从字符串:
1 2 3 4 5 6 7 8 9 10 11 12 | class C: def __init__(self, x): self.x = x print('Added new instance, x:', self.x) def call(str): obj = globals()[str](4) return obj c = call('C') print(c.x) |
它在"声明性python"中很有用。例如,在下面的
1 2 3 4 5 6 7 8 9 10 11 12 | # FooDef, BarDef are classes Foo_one = FooDef("This one", opt1 = False, valence = 3 ) Foo_two = FooDef("The other one", valence = 6, parent = Foo_one ) namelist = [] for i in range(6): namelist.append("nm%03d"%i) Foo_other = FooDef("a third one", string_list = namelist ) Bar_thing = BarDef( (Foo_one, Foo_two), method = 'depth-first') |
注意,这个配置文件使用一个循环来建立一个名称列表,这些名称是
该包使用如下内容读取配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | conf_globals = {} # make a namespace # Give the config file the classes it needs conf_globals['FooDef']= mypkgconfig.FooDef # both of these are based ... conf_globals['BarDef']= mypkgconfig.BarDef # ... on .DefBase fname ="user.conf" try: exec open(fname) in conf_globals except Exception: ...as needed... # now find all the definitions in there # (I'm assuming the names they are defined with are # significant to interpreting the data; so they # are stored under those keys here). defs = {} for nm,val in conf_globals.items(): if isinstance(val,mypkgconfig.DefBase): defs[nm] = val |
因此,最后要说的是,如果您想按程序创建一系列定义,那么在使用这样的包时,
1 2 3 | for idx in range(20): varname ="Foo_%02d" % i globals()[varname]= FooDef("one of several", id_code = i+1, scale_ratio = 2**i) |
这相当于写出
1 2 3 4 | Foo_00 = FooDef("one of several", id_code = 1, scale_ratio=1) Foo_01 = FooDef("one of several", id_code = 2, scale_ratio=2) Foo_02 = FooDef("one of several", id_code = 3, scale_ratio=4) ... 17 more ... |
一个包的例子是ply(python lex yacc)http://www.dabeaz.com/ply/—在这种情况下,对象主要是函数对象,但是来自函数对象(它们的名称、docstring和定义顺序)的元数据也构成了输入的一部分。这不是使用
我在一些项目中使用了"声明性python",并且在为这些项目编写配置时有机会使用
您还可以使用它根据变量的名称在配置文件中赋予变量重要性:
1 2 3 4 5 | # All variables above here starting with Foo_k_ are collected # in Bar_klist # foo_k = [ v for k,v in globals().items() if k.startswith('Foo_k_')] Bar_klist = BarDef( foo_k , method ="kset") |
这个方法对于定义大量表和结构的任何python模块都很有用,这样可以更容易地向数据添加项,而不必维护引用。