访问在封闭范围中定义的变量

时间:2017-09-02 22:47:43

标签: python python-3.x

来自词法范围的Google Style Guide

  

嵌套的Python函数可以引用封闭中定义的变量   功能,但不能分配给他们。

这两个似乎最初都要检查出来:

# Reference
def toplevel():
    a = 5
    def nested():
        print(a + 2)
    nested()
    return a
toplevel()
7
Out[]: 5

# Assignment
def toplevel():
    a = 5
    def nested():
        a = 7 # a is still 5, can't modify enclosing scope variable
    nested()
    return a
toplevel()
Out[]: 5

那么,为什么嵌套函数中引用和赋值的组合会导致异常呢?

# Reference and assignment
def toplevel():
    a = 5
    def nested():
        print(a + 2)
        a = 7
    nested()
    return a
toplevel()
# UnboundLocalError: local variable 'a' referenced before assignment

2 个答案:

答案 0 :(得分:8)

在第一种情况下,您指的是一个nonlocal变量,因为没有名为a的局部变量。

def toplevel():
    a = 5
    def nested():
        print(a + 2) # theres no local variable a so it prints the nonlocal one
    nested()
    return a

在第二种情况下,您创建一个局部变量a,这也很好(本地a将与非本地变量不同,这就是为什么原始a不是原来的def toplevel(): a = 5 def nested(): a = 7 # create a local variable called a which is different than the nonlocal one print(a) # prints 7 nested() print(a) # prints 5 return a 改变)。

print(a+2)

在第三种情况下,您创建一个局部变量但在此之前有print(a+2),这就是引发异常的原因。因为a将引用在该行之后创建的局部变量def toplevel(): a = 5 def nested(): print(a + 2) # tries to print local variable a but its created after this line so exception is raised a = 7 nested() return a toplevel()

nonlocal a

要实现您的目标,您需要在内部函数中使用def toplevel(): a = 5 def nested(): nonlocal a print(a + 2) a = 7 nested() return a

    int userInput=0;
    int endLoopCondition=1;//Meaning true
    do {
    // print out menu
    printf("================================== MENU ==================================== \n");
    printf("HELLO PLEASE CHOOSE 1 OPTION BELOW:                                          \n");
    printf("(1) CO2 reading and health advisory descriptor of a given classroom and time \n");
    printf("(2) 3 hourly average CO2 reading for a selected classroom                    \n");
    printf("(3) Highest CO2 reading from the classroom for a selected time               \n");
    printf("(4) Top 3 unhealthy readings for a selected classroom                        \n");
    printf("(5) List of time periods and classroom with above 'Average' value            \n");
    printf("(6) The unhealthiest classroom CO2 reading from 7am to 11am                  \n");
    printf("(7) QUIT                                                                     \n");
    printf("============================================================================ \n");
    printf("\n");

    // getting user input
    printf("Please enter your option: ");

    scanf_s("%d", &userInput); // put the user input into int userInput
    printf("\n");

    // check for the user input and run the function accordingly
    switch (userInput)
    {
        case 1: // if the user press 1
        {
            // call option1 function
            option1();
            break;
        }
        case 2:
        {
            // call option2 function
            option2();
            break;
        }
        case 3:
        {
            // call option3 function
            option3();
            break;
        }
        case 4:
        {
            // call option4 function
            option4();
            break;
        }
        case 5:
        {
            // call option5 function
            option5();
            break;
        }
        case 6:
        {
            // call option6 function
            option6();
            break;
        }
        case 7:
        {
            endLoopCondition=0; //when the user chose 7 the condition is false so the loop will stop
            break;
        }
    }
    } while (endLoopCondition);

答案 1 :(得分:0)

对于在此问题上绊脚石的任何人,除了此处接受的答案外,还可以在Python docs中简洁地回答:

  

此代码:

>>> x = 10
>>> def bar():
...     print(x)
>>> bar()
10
     

有效,但是此代码:

>>> x = 10
>>> def foo():
...     print(x)
...     x += 1
     

得到UnboundLocalError

     

这是因为当您对范围中的变量进行赋值时,   该变量成为该范围的局部变量,并以相似的方式阴影   外部作用域中的命名变量。自foo中的最后一条语句以来   为x分配一个新值,编译器将其识别为本地   变量。因此,当较早的print(x)尝试打印   未初始化的局部变量,并导致错误。

     

在上面的示例中,您可以通过以下方式访问外部范围变量   声明为global

>>> x = 10
>>> def foobar():
...     global x
...     print(x)
...     x += 1
>>> foobar()
10
     

您可以使用nonlocal在嵌套范围内执行类似的操作   关键字:

>>> def foo():
...    x = 10
...    def bar():
...        nonlocal x
...        print(x)
...        x += 1
...    bar()
...    print(x)
>>> foo()
10
11