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
yanyuechuixue
V2EX  ›  Python

在主函数外面定义的变量为什么跟在主函数里面定义的 global 变量不一样?

  •  
  •   yanyuechuixue · 2016-05-08 23:18:42 +08:00 · 2929 次点击
    这是一个创建于 3145 天前的主题,其中的信息可能已经有所发展或是发生改变。

    比如,如果我这么干,会报错 result 没有定义。

    import multiprocessing
    def func(msg):
        print(result)
    if __name__ == "__main__":
        pool = multiprocessing.Pool(processes=4)
        global result
        result=[]
        for i in range(3):
            msg = "hello %d" %(i)
            pool.apply(func, (msg, ))
        pool.close()
        pool.join()
    

    但如果我这么干,就不会报错:

    import multiprocessing
    
    result=[] #在这里定义
    
    def func(msg):
        print(result)
    if __name__ == "__main__":
        pool = multiprocessing.Pool(processes=4)
        for i in range(3):
            msg = "hello %d" %(i)
            pool.apply(func, (msg, ))
        pool.close()
        pool.join()
    

    Python 的多进程在内存上是“使用时复制”,所以,就算在主函数外面定义,也相当于在函数里面定义吧?

    第 1 条附言  ·  2016-05-09 00:39:38 +08:00
    是我弄错了,这个问题跟 golbal 没关系。
    我想问的是,多进程创建的时候为什么没有把 result 复制给子进程。。。
    但为什么写在 if 外面可以。
    第 2 条附言  ·  2016-05-09 00:49:43 +08:00
    问题解决了,是 pool 定义应该写在后面。
    谢谢
    4 条回复    2016-05-09 09:43:34 +08:00
    Ge4Los
        1
    Ge4Los  
       2016-05-09 00:18:55 +08:00
    在函数里面 global 其实是声明该变量为全局命名空间里的同名变量,不算定义。
    第 2 个例子是依据 LEGB 原则找到全局变量 result 。
    多进程的写时复制似乎与函数定义没必然联系,不太理解你最后一行的意义。
    yanyuechuixue
        2
    yanyuechuixue  
    OP
       2016-05-09 00:38:40 +08:00 via Android
    是我弄错了,这个问题跟 golbal 没关系。
    我想问的是,多进程创建的时候为什么没有把 result 复制给子进程。。。
    araraloren
        3
    araraloren  
       2016-05-09 09:03:27 +08:00
    拿`linux`下的`fork`来说,进程复制的是`fork`之前的父进程拥有的东西,`fork`之后的东西就不会再复制了。。
    yanyuechuixue
        4
    yanyuechuixue  
    OP
       2016-05-09 09:43:34 +08:00
    @araraloren 嗯,谢谢!
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5329 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 07:13 · PVG 15:13 · LAX 23:13 · JFK 02:13
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.