详解Python的作用域和命名空间

最近在学习Python,不得不说,Python真的是一门很好用的语言。但是学习的过程中关于变量作用域(scope)的命名空间(namespace)的问题真的把我给搞懵了。在查阅了相关资料之后,觉得自己对Python的作用域和命名空间有了一定得了解。故写在这里,一方面加深自己的理解,另一方面分享知识。

一、本篇博客需要解决的问题。

1、什么是作用域和命名空间?

2、Python中作用域和命名空间的工作原理是什么?

3、我怎样在Python中声明一个全局变量(global variable),局部变量(local variable)和nonlocal variable, which works between global scope and local scope?

4、如果我想让一个变量在多个Python脚本之间传递,我该怎么做?

二、解决问题

1、什么是作用域和命名空间?

命名空间是从名称到对象之间的映射。对象可以是Python脚本,函数,类等,也就是说Python中的每一个对象,都有其对应的命名空间。在不同的命名空间下声明相同名称的变量不冲突。

作用域是指Python程序运行时,一个命名空间相对应的作用范围的文本上的解释。英文原文为:A scope is a textual region of a Python program where a namespace is directly accessible. “Directly accessible” here means that an unqualified reference to a name attempts to find the name in the namespace.

2、Python中作用域和命名空间的工作原理是什么?

命名空间在不同的时间段被创建并且拥有不同的生命周期。有三种命名空间。

(1)、包含Python内置名称的命名空间。这种命名空间在Python编译器启动时被创建,在编译器关闭时销毁。

(2)、全局命名空间。即一个脚本文件(module)的命名空间。它在脚本文件被读取时创建,在编译器关闭时销毁。

(3)、局部命名空间。一般指一个函数的命名空间。在函数被调用时创建,在函数调用结束或者函数引发异常时销毁。

一个命名空间至少连接着三层相互嵌套的作用域。

(1)、the innermost scope,搜索变量时最先被搜索的作用域,包含local name

(2)、the scope of any enclosing functions,当(1)没有搜索到目标name时,就会向外扩张到一个封闭代码块或者函数的作用域,包含nonlocal name\nonglobal name

(3)、the next-to-last scope, 当(2)没有搜索到目标name时,搜索当前脚本和引用模块的name

(4)、the outermost scope,最后搜索的作用域,包含Python内置名称。

3、我怎样在Python中声明一个全局变量(global variable),局部变量(local variable)和nonlocal variable, which works between global scope and local scope?

Python中声明变量时,若前面不加关键字,这该变量默认为当前函数或代码块的局部变量

若前面加上global关键字,这意味着该变量是对一个全局变量的引用

若前面加上nonloca关键字,则意味着该变量是对中间层次作用域中的一个变量的引用

详情请看第三部分

4、如果我想让一个变量在多个Python脚本之间传递,我该怎么做?

简单。新建一个global.py脚本,把你需要用到的变量声明在里面,然后在需要用到这些变量的脚本里导入这个global.py脚本即可。

三、代码示例及相关解释

 1 # -*- coding: utf-8 -*-
 2 # author: zxr
 3 # time: 2019-04-07
 4 # functionality: test scope and namespace
# Python3.7.2
5 6 def scope_test(): 7 def do_local(): 8 spam = "local spam" 9 print (spam) 10 def do_nonlocal(): 11 nonlocal spam 12 spam = "do_local's nonlocal spam" 13 do_nonlocal() 14 print (spam) 15 def do_nonlocal(): 16 nonlocal spam 17 spam = "nonlocal spam" 18 def do_global(): 19 global spam 20 spam = "global spam" 21 spam = "test spam" 22 do_local() 23 print ("After local assignment, spam = " + spam) 24 do_nonlocal() 25 print ("After nonlocal assignment, spam = " + spam) 26 do_global() 27 print ("After global assignment, spam = " + spam) 28 29 if __name__ == '__main__': 30 scope_test() 31 print ("global spam = " + spam)

首先,调用scope_test函数的时候,scope_test.spam被声明,

然后,调用scope_test.do_local函数,scope_test.do_local.spam被声明

接着,调用scope_test.do_local.do_nonlocal函数,scope_test.do_local.spam被引用

接着,调用scope_test.do_nonlocal函数,scope_test.spam被引用

最后,调用scope_test.do_global函数,全局变量spam被声明

这段代码中,一定要仔细去理解每一个步骤,这样才能理解作用域和命名空间之间微妙的关系。

 

第一篇博客!

诚惶诚恐,希望有用!

若是无用,希望无害!

最后,如有不对的地方,欢迎大家批评指正!

 

转载于:https://www.cnblogs.com/xianranzhang/p/10666781.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值