1

我不确定 Python 的范围规则。如果我使用 Python 控制台并定义一个变量,然后导入一个模块并在该模块中调用一个函数,有没有办法在函数中引用该变量?例如:

>> option = 2
>> import choosingModule
>> choosingModule.choosingFunction()

然后在选择模块:

def choosingFunction():
    if option == 0:
        doThis()
    elif option == 1:
        doThat()
    elif option == 2:
        doTheOtherOne()
    else:
        doWhateverYouFeelLike()

显然这是一个简单的例子。我想这样做的原因是我有四个不同版本的函数,我希望能够从控制台中选择应该使用哪一个。该函数在代码中被调用得相当深入,所以我不想在每个函数调用中都传递一个参数,特别是因为我只需要在测试阶段比较它们;当它达到生产版本时,将只使用其中一个。

那么,有没有办法在被调用函数中引用 Python 控制台变量?还是有其他方法可以做我需要的事情?

4

2 回答 2

2

当您运行 REPL 时,您就是__main__模块,因此您可以导入它并使用其中的变量:

def choosingFunction():
    option = __import__('__main__').option
    if option == 0:
        doThis()
    elif option == 1:
        doThat()
    elif option == 2:
        doTheOtherOne()
    else:
        doWhateverYouFeelLike()

但是,如果您绝对不需要在控制台中定义变量,那么更好的方法是将其设置为choosingModule. 然后:

def choosingFunction():
    global option
    if option == 0:
        doThis()
    elif option == 1:
        doThat()
    elif option == 2:
        doTheOtherOne()
    else:
        doWhateverYouFeelLike()
>>> import choosingModule
>>> choosingModule.option = 2
>>> choosingModule.choosingFunction()

但是,您应该只在测试时使用其中之一。请不要在生产代码中使用这些。

于 2012-04-20T04:12:25.410 回答
0

我建议您将该变量保留在全局范围内并使用global语句访问它。

关键字global允许您在全局命名空间中引用一个变量,尽管函数调用者上存在另一个同名变量。

例如:这将打印“tangerine”

def foo():
    def bar():
        return fruit
    fruit = "tangerine"
    return bar2()

fruit = "banana"
print(foo()) # will print "tangerine"

但这将打印“香蕉”。

def foo2():
    def bar2():
        global fruit # fetch me the fruit in the global scope
        return fruit
    fruit = "tangerine"
    return bar2()

fruit = "banana"
print(foo2()) # will print "banana"

如果没有 global 关键字,解释器将遵循“LEGB 规则”来查找您尝试引用的变量:

  1. 本地范围:首先,它将在本地范围内搜索变量,即执行函数语句的范围。每次调用函数时都会创建局部范围。
  2. 封闭范围:其次,解释器将在“封闭函数局部变量”中查找变量,即插入(声明)函数的函数。这就是在bar()内的return fruit语句中找到fruit变量的地方。
  3. 全局:如果在上面的命名空间中找不到变量,python 将尝试在全局变量中找到它。global语句的使用迫使 python 只在全局范围内查找它,因此跳过了 1 和 2。
  4. B uiltins:最后,python 会尝试在内置函数和常量中查找变量。这里没有魔法。

如果上述所有搜索都找不到变量名,python 将引发NameError异常:

$ NameError: name 'fruit' is not defined

然后你可以这样做:

def choosingFunction():
    global option
    if option == 0:
        doThis()
    elif option == 1:
        doThat()
    elif option == 2:
        doTheOtherOne()
    else:
        doWhateverYouFeelLike()

>> option = 2
>> import choosingModule
>> choosingModule.choosingFunction()

请记住,依赖调用你的模块中存在的全局变量被认为是一种非常糟糕的做法,并且不能用于任何严重的事情。;)

有关global语句的更多信息,请查看文档:Python 3.xPython 2.7。有关范围和命名空间规则的信息,请查看此处(Python 3.x)或此处(Python 2.7)。

于 2012-04-20T05:01:11.057 回答