1 基本概念
1.1 命名空间 (namespace)
命名空间是变量名到对象的映射(name -> obj)。目前大多数的命名空间以类似于python字典的形式实现,实现形式在未来可能发生变化。命名空间举例:内置变量(内置函数abs, 内置的异常等),模块中的全局变量,函数调用时的局部变量。在某种意义上讲,对象的属性也形成一个命名空间。重要的是,不同的命名空间中的变量没有任何关联,两个不同的命名空间中可以包含相同的变量名。
命名空间有不同的创建时间和生命周期:
"background-color: #ccffcc">1.2 作用域 (scope)
作用域是Python程序中可以直接访问一个命名空间内变量的文本区域,可直接访问即命名空间内的变量在该文本区域内可见、可引用。
"htmlcode">
def func1(): name = 1 print(func1) # <function func1 at 0x101a03d08> print(name) # Traceback (most recent call last): # File "<stdin>", line 1, in <module> # NameError: name 'name' is not defined
本地作用域中的变量定义:
"htmlcode">
test = 'global variable' def scope_test(): def inner(): nonlocal test print(test) scope_test() # SyntaxError: no binding for nonlocal 'test' found
2 示例
2.1 本地作用域中变量的搜索遵守LEGB规则
1.L-Local(function):函数或类的命名空间,其中的变量称为本地变量
2.E-Enclosing function locals:外层函数的命名空间(例如closure),包含被声明为non-local的变量
3.G-Global(module):函数定义所在模块的命名空间,其中的变量称为全局变量
4.B-Builtin(Python):Python内置模块的名字空间
def scope_test(): def do_local(): spam = "local spam" def do_nonlocal(): nonlocal spam # 递归向上寻找上层函数命名空间中的spam变量 spam = "nonlocal spam" def do_global(): global spam # 在全局变量中寻找spam变量,没有则创建 spam = "global spam" spam = "test spam" do_local() print("After local assignment:", spam) # 输出本地变量 spam do_nonlocal() print("After nonlocal assignment:", spam) do_global() print("After global assignment:", spam) scope_test() print("In global scope:", spam)
结果
<SPAN style="FONT-SIZE: 14px">1 After local assignment: test spam After nonlocal assignment: nonlocal spam After global assignment: nonlocal spam In global scope: global spam </SPAN>
2.2 闭包
闭包:在嵌套函数中,如果内层函数引用了外层函数的变量,就形成了一个闭包。
自由变量:被引用的外层函数变量,称为内层函数的自由变量。
def fn(): a = 1 def closure(): nonlocal a a += 1 print(a) return closure inner = fn() print(inner.__closure__) # (<cell at 0x10240b408: int object at 0x100277bc0>,) inner() # 2 inner() # 3
外层函数执行完,其命名空间删除。但是因为 a 是内层函数的自由变量,所以变量 a 被保留,可以看作是 closure 函数对象的一个附加属性。
3 静态检测
3.1 本地变量
python是在编译def语句时静态检测其本地变量的。
a = 1 def local_test(): a += 1 print(a) local_test() # UnboundLocalError: local variable 'a' referenced before assignment print(b) # NameError: name 'b' is not defined
在编译local_test函数时,python就确定了变量 a 为函数的本地变量。所以在执行 a += 1 是会直接在本地命名空间寻找变量a。
3.2 命名空间搜索链
name = "lzl" def f1(): print(name) def f2(): name = "eric" f1() f2() # lzl
一个函数的变量搜索路径是在它定义的时候决定的,不受它调用位置的影响。
f1定义在全局作用域中,其变量的搜索路径为:本地命名空间 --> 模块命名空间。所以最后的输出结果为‘lzl'。
4 匿名函数
Python借助lambda关键字定义匿名函数,格式如下:
lambda 参数列表: 表达式
lambda x: x + 1 # 函数功能类型于下面的函数 def _(x): return x + 1
示例
下面一段代码的输出结果是什么:
li = [lambda :x for x in range(10)] print(li[0]())
其等价形式:
def fn(): return x li = [] for x in range(10): li.append(fn) li[0]() # fn() -> 9,根据变量搜索规则,x在函数中没有定义,在全局变量中查找
以上这篇浅谈python函数之作用域(python3.5)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。
python,函数作用域
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
P70系列延期,华为新旗舰将在下月发布
3月20日消息,近期博主@数码闲聊站 透露,原定三月份发布的华为新旗舰P70系列延期发布,预计4月份上市。
而博主@定焦数码 爆料,华为的P70系列在定位上已经超过了Mate60,成为了重要的旗舰系列之一。它肩负着重返影像领域顶尖的使命。那么这次P70会带来哪些令人惊艳的创新呢?
根据目前爆料的消息来看,华为P70系列将推出三个版本,其中P70和P70 Pro采用了三角形的摄像头模组设计,而P70 Art则采用了与上一代P60 Art相似的不规则形状设计。这样的外观是否好看见仁见智,但辨识度绝对拉满。
更新日志
- 雨林唱片《赏》新曲+精选集SACD版[ISO][2.3G]
- 罗大佑与OK男女合唱团.1995-再会吧!素兰【音乐工厂】【WAV+CUE】
- 草蜢.1993-宝贝对不起(国)【宝丽金】【WAV+CUE】
- 杨培安.2009-抒·情(EP)【擎天娱乐】【WAV+CUE】
- 周慧敏《EndlessDream》[WAV+CUE]
- 彭芳《纯色角3》2007[WAV+CUE]
- 江志丰2008-今生为你[豪记][WAV+CUE]
- 罗大佑1994《恋曲2000》音乐工厂[WAV+CUE][1G]
- 群星《一首歌一个故事》赵英俊某些作品重唱企划[FLAC分轨][1G]
- 群星《网易云英文歌曲播放量TOP100》[MP3][1G]
- 方大同.2024-梦想家TheDreamer【赋音乐】【FLAC分轨】
- 李慧珍.2007-爱死了【华谊兄弟】【WAV+CUE】
- 王大文.2019-国际太空站【环球】【FLAC分轨】
- 群星《2022超好听的十倍音质网络歌曲(163)》U盘音乐[WAV分轨][1.1G]
- 童丽《啼笑姻缘》头版限量编号24K金碟[低速原抓WAV+CUE][1.1G]