代码之家  ›  专栏  ›  技术社区  ›  Menda

关于变量作用域的正确性

  •  7
  • Menda  · 技术社区  · 16 年前

    我目前正在用python开发一些东西,我有一个关于变量范围的问题。

    这是代码:

    a = None
    anything = False
    if anything:
        a = 1
    else:
        a = 2
    
    print a # prints 2
    

    如果删除第一行(a=none),代码仍然像以前一样工作。但是,在这种情况下,我会在“IF”块中声明变量,而对于其他语言(如Java),该变量只能在“IF”内可见。

    在python中,变量作用域究竟是如何工作的?在这种情况下,编程的好方法是什么?

    谢谢!

    5 回复  |  直到 16 年前
        1
  •  8
  •   Shane Holloway    16 年前

    根据经验,作用域创建在三个位置:

    1. 文件作用域-也称为模块作用域
    2. 类作用域-在内部创建 class 阻碍
    3. 函数作用域-在内部创建 def 阻碍

    (有一些例外。)

    分配给名称会将其保留在作用域命名空间中,在到达第一个分配之前标记为未绑定。所以对于一个心智模型,你要给作用域中的名字赋值。

        2
  •  2
  •   Michael Williamson    16 年前

    我相信python对局部变量使用函数作用域。也就是说,在任何给定的函数中,如果将一个值赋给一个局部变量,则该值从该时刻起在该函数中可用,直到它返回。因此,由于您的代码的两个分支都保证分配给 a ,不需要分配 None 最初。

    注意,当您还可以访问外部函数中声明的变量时——换句话说,python有闭包。

    def adder(first):
        def add(second):
            return first + second
    
        return add
    

    它定义了一个名为adder的函数。当被叫来争论时 first ,它将返回一个函数,该函数将向 第一 并返回该值。例如:

    add_two = adder(2)
    add_three = adder(3)
    add_two(4) # = 6
    add_three(4) # = 7
    

    但是,尽管可以从外部函数读取值,但不能更改它(与许多其他语言不同)。例如,想象一下尝试实现累加器。你可以这样写代码:

    def accumulator():
        total = 0
        def add(number):
            total += number
            return total
        return add
    

    很遗憾,尝试使用此代码会导致错误消息:

    UnboundLocalError: local variable 'total' referenced before assignment
    

    这是因为 total += number 尝试更改的值 total ,但在python中不能这样做。

        3
  •  1
  •   John La Rooy    16 年前

    if 块。

    在本例中,它是在两个分支上分配的,因此您可以看到,当您来打印它时,它肯定会被定义。

    如果其中一个分支没有分配给 a 然后一个 NameError 当您尝试在该分支之后打印它时,将引发异常

        4
  •  0
  •   Skilldrick    16 年前

    python不需要最初声明变量,因此可以在任意点声明和定义。是的,作用域是函数作用域,所以它在 if

        5
  •  0
  •   japs    16 年前

    我是个初学者,但据我所知,在python中不存在私有变量。看见 private variables 在python文档中进行详细讨论。

    有用的信息也可以在同一页的“范围和名称空间”部分找到。

    就我个人而言,我编写的代码与您每天发布的代码非常相似,特别是当条件依赖于从用户那里获取输入时,例如

    if len(sys.argv)==2:
        f = open(sys.argv[1], 'r')
    else:
        print ('provide input file')
    

    在将变量用于结构化类型之前,我会先声明变量,例如,在将其项附加到循环中之前,我会声明一个空列表。

    希望有帮助。

    推荐文章