python上的前向声明与使用globals()

时间:2019-07-11 16:31:25

标签: python python-3.x

我有一个这样的全局命令:

mydict = {
   "name1" : {
       "description"   : "random text 1" ,
       "function_name" : foo
    }
}

这是没有if __name__ == "__main__":

的模块中的全局函数

这意味着我需要在引用foo之前声明它-根据我的尝试。否则,当我运行代码时,我得到'foo' is not defined

稍后我要执行的另一项功能是:

def randomCaller() :
   # ....
   mydict[ "name1" ][ "function_name"]()

由于我不想更改文件的结构,因此我可以选择使用名称并将上述代码更改为:

mydict = {
   "name1" : {
       "description"   : "random text 1" ,
       "function_name" : "foo"
    }
}
def randomCaller() :
   # ....
   fname = mydict[ "name1" ][ "function_name"]
   globals()[ fname ]()

以上是否有任何顾虑/风险?您会提出一些不同的建议吗?

1 个答案:

答案 0 :(得分:1)

@MarkMeyer在注释中为此提出了一个很好的解决方法:

"function_name": lambda *args, **kwargs: foo(*args, **kwargs)

(参数可以是您需要的任何参数。这是最灵活的安排,但是如果您知道foo()将使用一组特定的参数,则可以安排lambda来反映它。)

通常,这种lambda的使用将非常无用(“为什么不首先调用foo?”)。但是,在这种特殊的用例中,它非常有用,因为名称foo仅在调用lambda时才评估,而在分配时不评估。

换句话说,这可以在我的python控制台上工作:

>>> f1 = lambda: foo()
>>> f1()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 1, in <lambda>
NameError: name 'foo' is not defined
>>> def foo():
...     print("Hello World!")
...
>>> f1()
Hello World!

也就是说,该解决方案很笨拙,可能对名称空间玩得很奇怪。解决问题的最佳方法是在定义foo()之前先定义mydict,但是如果您绝对必须先声明mydict,也可以简单地声明首先是"function_name": None,然后在定义foo()之后将其设置为foo()

mydict = {
    "name1" : {
       "description"   : "random text 1" ,
       "function_name" : None
    }
}
...
def foo():
    ...
mydict["name1"]["function_name"] = foo