V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
redhatping
V2EX  ›  Python

Python 的全局变量的理解。

  •  
  •   redhatping · 2017-02-02 21:41:46 +08:00 · 3495 次点击
    这是一个创建于 2884 天前的主题,其中的信息可能已经有所发展或是发生改变。
    known = {0:0,1:1}
    a = [1,2,3]
    def example():
        known[2] =1
        a[2]=3
        print(known,a)
    
    example()
    
    #但是如果是下面
    
    been_called = Ture
    
    def example2():
        print(been_called)
        been_called = True
        print(been_called)
    
    语法错误,必须:
    def example2():
        global been_called
        print(been_called)
        been_called = True
        print(been_called)
    
    
    
    17 条回复    2017-02-04 11:30:39 +08:00
    rogerchen
        1
    rogerchen  
       2017-02-02 21:50:57 +08:00
    anti-pattern
    不要在函数 scope 里边乱动全局变量
    wangning3100
        2
    wangning3100  
       2017-02-02 21:57:10 +08:00
    第一个 example2 函数的第 2 行"been_called = True"把变量"been_called"定义成了该函数的局部变量,所以执行"print(been_called)"的时候"been_called"还没初始化,报 UnboundLocalError
    redhatping
        3
    redhatping  
    OP
       2017-02-02 21:59:48 +08:00
    @wangning3100 这个我知道, 为什么列表,字典不受影响。
    wangning3100
        4
    wangning3100  
       2017-02-02 22:03:37 +08:00
    @redhatping 因为你并没有在 example 函数里重新声明(初始化) a 和 know ,只是引用了而已
    wodesuck
        5
    wodesuck  
       2017-02-02 22:06:50 +08:00
    @redhatping 与列表字典无关,你试一下在 example()最后加一个 known={}就明白了
    redhatping
        6
    redhatping  
    OP
       2017-02-02 22:10:06 +08:00
    @wangning3100

    ```python

    count = 0

    def example4():
    count +=1



    这个也是引用也没有声明,但是语法也是错误的, 必须这样
    global count

    ```
    wangning3100
        7
    wangning3100  
       2017-02-02 22:15:15 +08:00
    @redhatping count += 1 === count = count + 1 ,重新声明了
    kindjeff
        8
    kindjeff  
       2017-02-02 22:20:40 +08:00 via iPhone
    去看看 python 里的可变对象和不可变对象。
    redhatping
        9
    redhatping  
    OP
       2017-02-02 22:22:12 +08:00
    @kindjeff 谢谢
    rocksolid
        10
    rocksolid  
       2017-02-02 22:32:48 +08:00   ❤️ 1
    yeyuexia
        11
    yeyuexia  
       2017-02-02 22:33:35 +08:00
    @redhatping 你字典只是引用 不是用 = 赋值 所以地址不变
    zzyzxd
        12
    zzyzxd  
       2017-02-03 03:11:44 +08:00
    如果你要在函数中改动全局变量,就必须有 global 声明。若光是读全局变量则不需要。

    你的第一个 example 里,读了全局变量 a ,但并没有改动 a (还是指向同一个 list )。具体来说,你干的事情是:读到了 list a ,取了第三个元素并把它 refer 到 3 。 dict 同理。
    20015jjw
        13
    20015jjw  
       2017-02-03 04:27:01 +08:00
    python 会 precheck 你的 scope 看你定一了 been_called 就认为是本地 variable 了
    Kilerd
        14
    Kilerd  
       2017-02-03 09:23:26 +08:00 via iPhone
    引用和非引用的区别
    robinlovemaggie
        15
    robinlovemaggie  
       2017-02-03 10:20:38 +08:00
    "UnboundLocalError: local variable 'been_called' referenced before assignment",
    摘取 stackoverflow 的解释——
    Basically the rule is: If you try to assign a global variable from within a function, you need to use the global keyword within that function. Otherwise you don't need the global keyword at all. Whether or not the variable is a boolean makes no difference.
    XYxe
        16
    XYxe  
       2017-02-04 08:37:28 +08:00
    最内嵌套作用域规则:由一个赋值语句引进的名字在这个赋值语句所在的作用域里是可见(起作用)的,而且在其内部嵌套的每个作用域里也可见,除非它被嵌套与内部的,引进同样名字的另一条赋值语句所遮蔽。
    billytv
        17
    billytv  
       2017-02-04 11:30:39 +08:00
    楼主的 True 拼写错为 Ture, 没人发现吗?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1076 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 19:35 · PVG 03:35 · LAX 11:35 · JFK 14:35
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.