在Lua中,全局变量存储在名为<button onClick={this.removeContact(index)}>
的表中。您可以向_G
添加一个元表,这样当您查找未定义的全局值时,将调用用户定义的函数来提供一个值。
在下面的示例中,查找任何未定义变量将返回未定义变量的名称。
_G
是否可以在Python 3中实现相同的效果?
答案 0 :(得分:0)
从2018年12月12日起更新答案:
这是另一种(更好的方法)。基本上,我们手动read()
,compile()
,然后exec()
整个源文件。当我们调用exec()
时,我们可以传入备用全局字典。整个文件被读取,编译和执行两次,但是我们确实达到了预期的结果。
def baz ():
global foo
print ( foo ) # should print the string 'foo'
foo = 5
print ( foo ) # should print 5
print ( bar ) # should print the string 'bar'
class CustomGlobals ( dict ):
def __getitem__ ( self, k ):
if k in self: return self .get ( k )
if hasattr ( self .get ( '__builtins__' ), k ):
# we raise KeyError to avoid clobbering builtins
raise KeyError
return k
def main ():
with open ( __file__, 'rb' ) as f:
source = f .read() # re-read __file__
code = compile ( source, __file__, 'exec' ) # re-compile __file__
g = CustomGlobals ( globals() )
g [ '__name__' ] = None # prevent infinite recursion
exec ( code, g ) # re-exec __file__ against g
g [ 'baz' ] () # call the re-complied baz function
if __name__ == '__main__': main()
以上方法(IMO)优越,因为我们不需要将代码嵌套在字符串中,并且错误消息将包含正确的行号。
2018年11月29日的原始答案:
如果有问题的Python代码来自字符串(而不是标准的.py
文件),则可以exec()
字符串并提供一个自定义全局字典,如下所示:
code = '''
print ( foo ) # should print the string 'foo'
foo = 5
print ( foo ) # should print 5
print ( bar ) # should print the string 'bar'
'''
class CustomDict ( dict ):
def __init__ ( self, other ): super() .__init__ ( other )
def __getitem__ ( self, k ):
if k in self: return self .get ( k )
if hasattr ( self .get ( '__builtins__' ), k ):
# we raise KeyError to avoid clobbering builtins
raise KeyError
return k
exec ( code, None, CustomDict ( globals() ) )
根据需要,以上输出:
foo
5
bar
我还没有找到任何使模块“突变”以实现该模块中代码相同结果的方法。如果有人知道改变模块的方法,我将很高兴看到它。
(也许模块可以将自己的源代码读取为字符串,然后在自定义全局dict
的上下文中编译该字符串,然后将结果注入sys.modules
?换句话说,该模块将用自身的克隆代替自身,但使用不同的全局dict
。嗯。)
此外:有一些方法可以在模块上模拟__getitem__()
和__getattr__()
。从Python 3.7开始,您可以在模块中直接简单地定义一个__getattr__()
函数。但是,据我所知,这些技术都无法与全局变量的查找挂钩。来源:
答案 1 :(得分:-1)
你是说类似的东西
print(bar) if 'bar' in globals() else print('bar')