Python函数学习笔记
2023-06-13 09:14:02 时间
局部名字静态检测
Python探测局部作用域的时候:是在python编译代码时检测,而不是通过他们在运行时的赋值。
正常的情况下,没在函数中复制的名字将在包含它的模块中查找:
>>>x=99
>>>defselector():
...printx
...
>>>selector()
99
但是:
>>>defselector():
...printx
...x=100
...
>>>selector()
Traceback(mostrecentcalllast):
File"<stdin>",line1,in?
File"<stdin>",line2,inselector
UnboundLocalError:localvariable"x"referencedbeforeassignment
会得到未定义名字的错误。
当交互式输入或从一个模块中导入时,python读取并编译这段代码,当编译时python查看x的赋值,并决定在函数中任何地方x都将是个局部名字。到后来函数真的运行,print执行时,赋值还没有发生,python会说你正在使用一个未定义的名字。根据他的名字规则,应该是局部的x在赋值前被使用了。
解决办法:
如果你想打印全局x,你应该在global语句中声明:(这意味着该赋值也改变全局x,而不是局部x)
>>>defselector():
...globalx
...printx
...x=88
...
>>>selector()
99
如果你想打印出全局赋值,在设定一个局部的,导入包含它的模块并用限定得到这个全局的版本:
>>>x=99
>>>defselector():
...import__main__
...print__main__.x
...x=88
...printx
...
>>>selector()
99
88
限定(.x部分)从一个名字空间对象中得到一个值。交互环境的名字空间是一个叫做__main__的模块。
嵌套函数可以嵌套作用域(在新版本中和老版本中不同)
>>>defouter(x):
...definner(i):
...printi,
...ifi:inner(i-1)
...inner(x)
...
>>>outer(3)
3210
使用默认值保存引用
>>>defouter(x):
...definner(i,self=inner):
...printi,
...ifi:self(i-1)
...inner(x)
...
>>>outer(3)
Traceback(mostrecentcalllast):
File"<stdin>",line1,in?
File"<stdin>",line2,inouter
UnboundLocalError:localvariable"inner"referencedbeforeassignment
解决原则:最简单的方式总是最正确的方式
>>>definner(i):
...printi,
...ifi:inner(i-1)
...
>>>defouter(x):
...inner(x)
...
>>>outer(3)
3210
默认的可变对象
>>>defsaver(x=[]):
...x.append(1)
...printx
...
>>>saver([2])
[2,1]
>>>saver()
[1]
>>>saver()
[1,1]
>>>saver()
[1,1,1]
问题是,这里只有一个列表对象——def执行时生成的一个。在每一次函数被调用时,你不会得到新的列表对象,而是原列表对象的增长。
解决办法:如果那不是你想要的行为,简单的移动默认值到函数体中。只要代码里的值在每一次函数运行时都执行,你每次将得到一个新的对象:
>>>defsaver(x=None):
...ifxisNone:
...x=[]
...x.append(1)
...printx
...
>>>saver([2])
[2,1]
>>>saver()
[1]
>>>saver()
[1]
>>>saver()
[1]
上面的if语句几乎可以被赋值x=xor[]代替,因为python的or将返回他的操作对象中的一个:如果没有参数被传递,x默认为None,所以or在右侧返回一个生成的空列表。但这不完全一样,当传递的是空列表时,函数将扩展并返回一个新生成的列表,而不是向前面的版本那样扩展并返回一个被传递的列表(表达式变成[]or[],这将计算出新的列表)
Python探测局部作用域的时候:是在python编译代码时检测,而不是通过他们在运行时的赋值。
正常的情况下,没在函数中复制的名字将在包含它的模块中查找:
>>>x=99
>>>defselector():
...printx
...
>>>selector()
99
但是:
>>>defselector():
...printx
...x=100
...
>>>selector()
Traceback(mostrecentcalllast):
File"<stdin>",line1,in?
File"<stdin>",line2,inselector
UnboundLocalError:localvariable"x"referencedbeforeassignment
会得到未定义名字的错误。
当交互式输入或从一个模块中导入时,python读取并编译这段代码,当编译时python查看x的赋值,并决定在函数中任何地方x都将是个局部名字。到后来函数真的运行,print执行时,赋值还没有发生,python会说你正在使用一个未定义的名字。根据他的名字规则,应该是局部的x在赋值前被使用了。
解决办法:
如果你想打印全局x,你应该在global语句中声明:(这意味着该赋值也改变全局x,而不是局部x)
>>>defselector():
...globalx
...printx
...x=88
...
>>>selector()
99
如果你想打印出全局赋值,在设定一个局部的,导入包含它的模块并用限定得到这个全局的版本:
>>>x=99
>>>defselector():
...import__main__
...print__main__.x
...x=88
...printx
...
>>>selector()
99
88
限定(.x部分)从一个名字空间对象中得到一个值。交互环境的名字空间是一个叫做__main__的模块。
嵌套函数可以嵌套作用域(在新版本中和老版本中不同)
>>>defouter(x):
...definner(i):
...printi,
...ifi:inner(i-1)
...inner(x)
...
>>>outer(3)
3210
使用默认值保存引用
>>>defouter(x):
...definner(i,self=inner):
...printi,
...ifi:self(i-1)
...inner(x)
...
>>>outer(3)
Traceback(mostrecentcalllast):
File"<stdin>",line1,in?
File"<stdin>",line2,inouter
UnboundLocalError:localvariable"inner"referencedbeforeassignment
解决原则:最简单的方式总是最正确的方式
>>>definner(i):
...printi,
...ifi:inner(i-1)
...
>>>defouter(x):
...inner(x)
...
>>>outer(3)
3210
默认的可变对象
>>>defsaver(x=[]):
...x.append(1)
...printx
...
>>>saver([2])
[2,1]
>>>saver()
[1]
>>>saver()
[1,1]
>>>saver()
[1,1,1]
问题是,这里只有一个列表对象——def执行时生成的一个。在每一次函数被调用时,你不会得到新的列表对象,而是原列表对象的增长。
解决办法:如果那不是你想要的行为,简单的移动默认值到函数体中。只要代码里的值在每一次函数运行时都执行,你每次将得到一个新的对象:
>>>defsaver(x=None):
...ifxisNone:
...x=[]
...x.append(1)
...printx
...
>>>saver([2])
[2,1]
>>>saver()
[1]
>>>saver()
[1]
>>>saver()
[1]
上面的if语句几乎可以被赋值x=xor[]代替,因为python的or将返回他的操作对象中的一个:如果没有参数被传递,x默认为None,所以or在右侧返回一个生成的空列表。但这不完全一样,当传递的是空列表时,函数将扩展并返回一个新生成的列表,而不是向前面的版本那样扩展并返回一个被传递的列表(表达式变成[]or[],这将计算出新的列表)
相关文章
- Python 学习笔记 列表 xxx XXX
- python win32api messagebox_如何在Python中使用Win32 API?
- python中矩阵的转置_[转]Python中的矩阵转置[通俗易懂]
- Python学习笔记(15)-Python代码转换为exe可执行程序详解
- Python机器学习笔记:不得不了解的机器学习面试知识点(1)[通俗易懂]
- python中关于命名的例子_Python 命名规范入门实例「建议收藏」
- python语言一般用于什么_PYthon
- Python学习笔记(七)·面向对象高级编程
- python zipfile_Python 学习入门(16)—— zipfile
- python图像多层小波分解_Python中图像小波分解与重构以及灰度图加噪
- python廖雪峰学习笔记[通俗易懂]
- python lambda表达式 if_Python学习-lambda表达式
- python里面的缩进是什么意思_Python缩进规则(一看即懂)[通俗易懂]
- 关于python中lambda函数的描述_Python全局变量
- 全网最详细超长python学习笔记、14章节知识点很全面十分详细,快速入门,只用看这一篇你就学会了!
- Python电子邮件——学习笔记详解编程语言
- Python网络编程——学习笔记详解编程语言
- Python学习笔记之三lambda表达式用法小结详解编程语言
- Python学习笔记之一Python关键字及其总结详解编程语言
- python学习笔记之运算符详解编程语言
- Python requests模块学习笔记详解编程语言
- 快速查询MySQL数据库:Python篇(python查询mysql数据库)
- Python与Linux:开启互联网信息技术时代(python和linux)
- 王纯业的Python学习笔记下载
- Python学习笔记(一)(基础入门之环境搭建)
- python网络编程学习笔记(四):域名系统
- python网络编程学习笔记(七):HTML和XHTML解析(HTMLParser、BeautifulSoup)