在函数中引用Python控制台变量

时间:2012-04-20 04:07:58

标签: python variables console scope

我不确定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控制台变量?或者是否有其他方法可以做我需要的事情?

2 个答案:

答案 0 :(得分:1)

当你运行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()

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

答案 1 :(得分: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. L ocal范围:首先,它将搜索本地范围中的变量,即执行函数语句的范围。每次调用函数时都会创建本地范围。
  2. E nclosing Scopes:其次,解释器将在“封闭函数locals”中查找变量,即插入(声明)函数的函数。这就是在 bar()内的 return fruit 语句中找到 fruit 变量的地方。
  3. G lobal:如果在上面的命名空间中找不到变量,python将尝试在全局变量中找到它。 global 语句的使用迫使python仅在全局范围内查找它,因此跳过1和2.
  4. B uiltins:最后,python将尝试在内置函数和常量中查找变量。这里没有魔力。
  5. 如果上面的所有搜索都找不到变量名,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()
    

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

    有关全局语句的详细信息,请查看文档:{​​{3}}和Python 3.x。 有关范围和命名空间规则的信息,请检查Python 2.7(Python 3.x)或here(Python 2.7)。