为啥我的看今日头条怎么赚钱首页没有关注

python(39)
python 函数简介
def 是一个可执行的语句,当执行到def时首先创建一个对象并且将其变量(即函数名),此时函数名成了这个函数的应用
函数参数通过赋值(即对象引用)传递的
参数 返回值和变量不是声明
&&&test='a'
&&& if test=='a':
def func():
print test
def func():
print test+'not'
&&& func()
&&& othername=func
&&& othername()
函数内的本地变量:
在函数内被赋值了的变量
参数是通过赋值传入的所以参数也是本地变量
返回值也是本地变量
&&& a='sdfsdaf'
&&& def cc():
a='324234'
x='324wer'
&&& print a
&&& print x //函数外就无法访问函数内的本地变量了
Traceback (most recent call last):
& File &&pyshell#32&&, line 1, in &module&
& & print x
NameError: name 'x' is not defined
函数的命名空间
一个变量的作用域总是由在代码中被赋值的地方所决定的,并且与函数调用完全没有关系,如果一个变量在def内被赋值,它总是被定为的函数内访问,如果在def外被赋值
它就是整个文件全局的并且称之为语义作用域
在默认的情况下,一个函数的所有的变量名都是与函数的命名空间相关联的:
一个在def内定义的变量名能够被def内的代码使用,不能再函数的外部引用这样的变量名
def之中的变量名与def之外的变量名并不冲突,即使是使用在别处的相同的变量名
函数作用域的基础:
函数提供的是嵌套的的命名空间,使其内部使用的变量名本地化,不会与外部的变量名冲突,模块定义的是全局作用域
内嵌的模块是全局作用域,全局作用域的作用域仅局限于单个文件
每次函数的调用都创建了一个新的本地作用域
默认情况下函数内部被赋值的变量名除非声明为全局变量(使用 global)否则均为本地变量
所有的变量名都可以归纳为本地,全局或者内置的
在函数内部定义的任意的赋值操作定义的变量名都将成为本地变量:=语句,import语句,def语句,参数传递
但是在函数内部实地改变对象不会吧变量划分为本地变量
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:30234次
排名:千里之外
原创:61篇
转载:12篇> 原来Python装饰器就是这么个东西这是我自己的理解,如有不妥,请指正其实弄明白了python中的
原来Python装饰器就是这么个东西这是我自己的理解,如有不妥,请指正其实弄明白了python中的
liyangqsh & &
发布时间: & &
浏览:31 & &
回复:0 & &
悬赏:0.0希赛币
原来Python装饰器就是这么个东西
这是我自己的理解,如有不妥,请指正其实弄明白了python中的嵌套函数(也就是所谓的闭合函数)之后,再想搞懂python装饰器就简单多了。总之python装饰器不过就是一个针对嵌套函数的语法糖它的作用就是在函数调用方法不变的情况下,把此函数包装成另一个函数来使用一、首先来大致了解下嵌套函数:被嵌套与一层函数中的二层函数可以记录上上一层函数作用域中的变量举例:  def foo(a):
def subfoo(b):
return(b + a)
return(subfoo)
f = foo('content') #由于foo返回的是subfoo,所以f是对subfoo的引用
f('sub_') #因为subfoo记录了foo的参数变量'content',所以返回值为'sub_content'
二、嵌套函数和它的变种(装饰器)以下两端代码,作用是相同的,前一个是大姑娘,后一个是女扮男装后的大姑娘  def action(x):
def action_pro(n):
def warpper(x):
return(n(x) * x)
return(warpper)
action = action_pro(action) #第一个action为自定义的伪装变量,第二个action为上边定义的action函数
action(3) #此函数实际为warpper(3),返回值为9
将上边代码改写:  def action_pro(n):
def warpper(x):
return(n(x) * x)
return(warpper)
@action_pro #用action_pro函数把action包装成warpper
def action(x):
action(3) #此函数实际为warpper(3),返回值为9
本问题标题:
本问题地址:
温馨提示:本问题已经关闭,不能解答。
暂无合适的专家
&&&&&&&&&&&&&&&
希赛网 版权所有 & &&循序渐进学Python之函数的嵌套
我的图书馆
循序渐进学Python之函数的嵌套
【51CTO独家特稿】我们在上一篇文章即“”中介绍了函数的定义和调用方法,那里定义的函数都是相互平行的,也就是说,所有函数都是在其它函数之外定义的。而本文介绍的是函数的嵌套:即函数内部的函数。我们这里首先介绍了嵌套函数的定义,以及嵌套函数中变量的查找过程,然后后讲解多层嵌套函数的执行过程,最后说明了嵌套作用域的静态性。
一、函数的嵌套定义
学习过C语言的读者都知道,C语言的函数定义都是相互独立的,也就是说,在定义函数的时候,不能在这个函数内部包含其它函数的定义。但是Python语言正好与之相反,它允许在定义函数的时候,其函数体内又包含另外一个函数的完整定义,这就是我们通常所说的嵌套定义。为什么?因为函数是用def语句定义的,凡是其他语句可以出现的地方,def语句同样可以出现。像这样定义在其他函数内的函数叫做内部函数,内部函数所在的函数叫做外部函数。当然,我们可以多层嵌套,这样的话,除了最外层和最内层的函数之外,其它函数既是外部函数又是内部函数。
下面是一个内部函数的例子:
char='hello'
print char
上面的定义在交互方式下的运行情况如下所示:
图1& 函数的嵌套定义
二、嵌套函数的作用域
内部函数定义的变量只在内部有效,包括其嵌套的内部函数,但是对外部函数无效,如下例所示:
print '''目前在函数f1()中:x=''', x
print '''目前在函数f2()中:x=''', x
对于上面的代码,我们定义了三个函数,其中函数f()是函数f1()的外部函数,而函数f1()又是函数f2()的外部函数。在这三个函数中我们仅定义了一个变量x,并且该变量是在函数f1()中定义的,然后我们分别在函数f1()和它的内部函数f2()中打印该变量的值。在交互式环境下的执行情况如下所示:
&图2& 内部函数可以使用外部函数的变量
上图说明内部函数可以引用外部函数中定义的变量,但是外部函数却不能引用内部函数定义的变量,例如:
print '''目前在内部函数f1()中:'''
print 'x=',x,'y=',y
print '''目前在外部函数f2()中:'''
print 'x=',x,'y=',y
在上面的示例代码中,我们在外部函数f()中定义了一个变量x,然后又在内部函数f1()中定义了一个变量y;然后分别在内部函数和外部函数中引用这两个变量,代码的交互式执行情况如下所示:
图3& 外部函数不可以使用内部函数的变量
很明显,程序在引用内部变量的时候出错了,因为内部函数定义的变量只对这个函数本身及其内部函数可见,而不对其外部函数可见,所以在外部函数f()看来,变量y尚未定义。
三、变量的四种作用域
介绍了嵌套的内部函数之后,我们已经接触到了Python中变量的四种作用域,它们分别是局部作用域、全局作用域、外部作用域和Python内建的作用域。其中,局部作用域对应于函数本身,外部作用域对应于外部函数(如果有的话),全局作用域对应于模块(或文件),Python内建的作用域对应于Python解释程序。这四种作用域的包含关系如下所示:
图4& 变量的四种作用域
四、Python内建的作用域
通过阅读本系列的文章,相信读者对于局部作用域、全局作用域和外部作用域已经有所了解了,现在我们再来介绍一下有效范围最大,即对应于Python解释程序范围的Python内建的作用域。
实际上,Python解释程序有一个预建的,或者叫自带的模块,叫做__builtin__。我们可以在Python解释程序中导入该模块,并查看其中预定义的名称。如下图所示:
图5& 查看__builtin__模块中预定义的名称
上图为我们展示了Python内建的作用域中已定义的所有名称,其中大部分一些是变量名,一些是函数名。如果有兴趣的话,可以直接在提示符下输入这些名称,来引用它们,如:
图6& 引用内建的函数名
当我们在提示符下面输入上面列出的函数名时,系统提示这些是内建的函数名。
五、变量名的查找顺序
上面说过,Python中的变量有四种作用域,那么当函数引用一个变量时,它是以怎样的顺序在这些作用域中查找变量呢?下面我们将详细说明。
当某个函数引用一个变量时,比如变量x,它首先在该函数的局部作用域中查找该变量,如果在局部作用域中有对该变量的赋值语句,并且没有用关键词global,即没有将其声明为全局变量,如下所示:
这相当于在该函数内部定义了一个局部变量,那么这个名为x值为6的整型变量就是我们要找的。如果在当前函数的局部作用域中没有找到该变量的定义,并且当前函数是某个函数的内部函数的话,那么继续由内向外在所有外部函数中查找该变量的定义,并且将最先找到的赋值语句作为它的定义,并将第一个赋给它的值作为我们要找的变量的值。如果在所有外部函数中都没有找到该变量的定义,或者根本就没有外部函数,那么继续在全局作用域中查找。如果在全局作用域中还没有找到x的定义,那么就到Python内建的作用域去找,如果四个作用域都没找到的话,则说明引用了一个未加定义的变量,这时Python解释器就会报错。
读者可以对照图4进行理解。
下面我们以示例代码进行讲解,代码如下所示:
print '目前在函数f3()中,变量x的值为:',x
print '目前在函数f2()中,变量x的值为:',x
print '目前在函数f1()中,变量x的值为:',x
print '目前在函数f()中,变量x的值为:',x
上述代码中出现了多层嵌套的函数,其中函数f3()嵌套在函数f2()中,函数f2()嵌套在函数f1()中,函数f1()嵌套在函数f()中。但是,每个函数中都对变量x进行了定义,所以各个函数都能在其局部定义域中找到变量x。上述代码在交互式环境下的执行结果如下所示:
图7& 在局部作用域中找到变量x的情形
在函数f()中,变量x被赋值为0,根据查找变量时先从当前函数的局部作用域下手的规则,函数f()看到的变量x的值就是0,其它函数依此类推。
现在我们对上述代码稍作修改,将函数f3()和函数f2()中对变量x的定义去掉,看一下在当前函数中找不到变量的定义时的情形,代码如下所示:
print '目前在函数f3()中,变量x的值为:',x
print '目前在函数f2()中,变量x的值为:',x
print '目前在函数f1()中,变量x的值为:',x
print '目前在函数f()中,变量x的值为:',x
上述修改后的代码在交互环境下执行情况如下所示:
图8&& 在局部作用域中找不到变量x的情形
从图8可以看出,在函数f3()、f2()、f1()中,变量的值都为1;只有在f0()中变量的值为0。对于函数f3()来说,当它打印变量x的值时,首先在其局部作用域中寻找变量x的定义,因为没有找到,所以继续向外到其外部函数f2()中寻找,结果在函数f2()的局部变量中也没有找到变量x的定义,所以又向函数f2()的外部函数即函数f1()中寻找,这次找到了变量x的定义,即
所以函数f3()打印的变量x的值为1。当函数f2()执行时,首先在其局部作用域中寻找变量x的定义,没找到,所以继续向外部函数f1()中寻找,这次找到了变量x的定义,即
所以函数f2()打印的变量x的值为1。当函数f1()执行时,首先在其局部作用域中寻找变量x的定义,在其局部作用域中找到了变量x的定义,其值为1,所以直接打印变量x的值。同理,当函数f()执行时,首先在其局部作用域中寻找变量x的定义,在其局部作用域中找到了变量x的定义,其值为0,所以直接打印变量x的值。
需要注意的是,如果内部函数将变量声明为全局变量,那么Python就会跳过局部作用域和外部作用域,而直接从全局作用域开始寻找该变量的定义。现在举例说明:
#定义一个全局变量
#定义一个局部变量
print '在函数f()中,x=',x
#将x声明为全局变量
#这个赋值语句并没有定义局部变量,而是修改了全局变量的值
print '在函数f1()中,x=',x
print '现在函数f()中,x=',x
上面的代码以交互式执行,结果如下所示:
&图9& 在内部函数中使用全局变量的情形
从图10可以看出,当函数f1()执行后,其外部函数f()的局部变量并没有发生变化,但是全局变量x的值却变了。这是因为,当在内部函数f1()中将变量x声明为全局变量后,赋值语句
的作用并不是在当前函数中定义一个局部变量,因为这时函数f1()会直接到全局作用域中查找变量,所以赋值语句实际的作用是修改了全局变量x的值。
六、函数嵌套时的执行顺序
当初学者遇到多层嵌套的函数时,对于各个函数的执行顺序经常感到非常头疼,不过不要紧,我们这里向大家介绍一种非常简单的办法,让您轻松读懂代码的执行顺序。
我们曾经说过,在使用def语句定义函数时,Python遇到该语句并不会立即执行其语句体中的代码,只有遇到该函数的调用时,对应def语句的语句体才会被执行。所以,当我们分析嵌套函数的执行顺序时,遇到def语句可以先行跳过(包括其语句体),然后遇到函数调用时,在返回头来查看对应def语句的语句体。我们以下列代码进行说明:
print '当前正在执行函数f(),其变量x的值为:',x
print '当前正在执行函数f1()中,其变量x的值为:',x
print '当前正在执行函数f2()中,其变量x的值为:',x
print '当前正在执行函数f3()中,其变量x的值为:',x
上述代码在交互式环境下的执行情况如下所示:
图10& 多层嵌套函数执行顺序示例1
现在分析一下上述代码的执行过程。首先,当我们在命令提示符下调用函数f()时,解释器会寻找到该函数的定义。在函数f()的定义的第一行下面,虽然这里的代码很多,但是我们只关心冒号下面的第一次缩进所涉及的那些语句,在这里有四个语句,一个赋值语句,一个打印语句,一个def语句,一个函数调用语句。注意,这里的def语句及其语句体可以先跳过去。所以,除了def语句外,这四条语句的执行顺序基本上是顺序执行的,即先给变量x赋值,令其为整数0,再输出变量x的值,这时系统将输出:
当前正在执行函数f(),其变量x的值为: 0
然后调用f1(),最后找到定义f1()的def语句,并执行其语句体。我们看到,在定义f1()的def语句下面的第一次缩进对应有四条语句,分别也是一个赋值语句,一个打印语句,一个def语句,一个函数调用语句。执行时,先赋值,即将变量x赋值为1,再打印,系统输出以下内容:
当前正在执行函数f1()中,其变量x的值为: 1
遇到def语句先跳过,继而执行函数调用,这次调用的是函数f2()。我们找到定义该函数的def语句,并执行该语句第一行下面第一次缩进对应的四条语句。首先将变量x赋值为2,再打印,系统输出以下内容:
当前正在执行函数f2()中,其变量x的值为: 2
接着,先跳过def语句,直接执行函数调用,这次调用的是函数f3()。我们找到定义该函数的def语句,并执行其第一行下面第一次缩进对应的两条语句。首先将变量x赋值为3,再打印变量的值,如下所示:
当前正在执行函数f3()中,其变量x的值为: 3
好了,至此这个多层嵌套的函数的执行过程至此分析完毕。作为一个练习,读者可以按照上面介绍的方法分析一下下列代码,然后在交互环境中执行一下,看看分析的对不对:
print '目前在函数f3()中,变量x的值为:',x
print '目前在函数f2()中,变量x的值为:',x
print '目前在函数f1()中,变量x的值为:',x
print '目前在函数f()中,变量x的值为:',x
七、嵌套作用域的静态性
前面说过,函数内定义的变量局部只有在函数执行时有效,当函数退出后就不能再访问了,例如下列代码:
当我们在交互方式下执行上述代码时,结果如下:
图11& 局部变量的动态性
当我们在函数中引用局部变量时,完全合法。但是,一旦函数退出,再次引用函数内的局部变量就会出错。这是因为局部变量是动态分配的,当函数执行时为其分配临时内存,函数执行后马上释放。这反映出局部变量的动态性。但是当出现函数嵌套时,情况会有所变化。请看下列代码:
我们在交互环境下执行上述代码,如:
图12& 嵌套作用域的动态性
我们说明一下上面的代码。首先,我们在函数f()中定义了一个局部变量x和一个内部函数f1(),最后将内部函数名作为返回值。注意,我们在内部函数f1()中引用了外部函数f()的局部变量。我们在命令提示符下调用函数f(),并将返回值赋给printx,这时变量printx中实际上存放的是内部函数f1()的函数名f1。所以在命令行中输入printx()实际上就是在调用内部函数f1()。然后内部函数执行,并引用外部函数f()的局部变量x。这说明,发生函数嵌套后,如果内部函数引用了外部函数的局部变量,那么外部函数的局部变量将被静态存储,即当函数退出后,其局部变量所占内存也不会被释放。
在本文中,我们为读者介绍了函数的嵌套。除了嵌套函数的定义外,我们详细解释了嵌套函数中变量的查找过程以及相关的四种作用域,然后后讲解多层嵌套函数的执行过程,最后说明了嵌套作用域的静态性。为了帮助读者理解本文内容,我们给出了大量示例代码,读者可以利用这些代码实际运行、分析,从而加深理解。
【相关文章】
【责任编辑: TEL:(010)】
TA的最新馆藏python变量和作用域 - 推酷
python变量和作用域
1、作用域介绍
python中的作用域分4种情况:
L:local,局部作用域,即函数中定义的变量;
E:enclosing,嵌套的父级函数的局部作用域,即包含此函数的上级函数的局部作用域,但不是全局的;
G:globa,全局变量,就是模块级别定义的变量;
B:built-in,系统固定模块里面的变量,比如int, bytearray等。
搜索变量的优先级顺序依次是:作用域局部&外层作用域&当前模块中的全局&python内置作用域,也就是LEGB。
x = int(2.9)
# int built-in
g_count = 0
def outer():
o_count = 1
# enclosing
def inner():
i_count = 2
当然,local和enclosing是相对的,enclosing变量相对上层来说也是local。
2、作用域产生
在Python中,只有模块(module),类(class)以及函数(def、lambda)才会引入新的作用域,其它的代码块(如if、try、for等)是不会引入新的作用域的,如下代码:
这个是没有问题的,if并没有引入一个新的作用域,x仍处在当前作用域中,后面代码可以使用。
def test():
# NameError: name 'x2' is not defined
def、class、lambda是可以引入新作用域的。
3、变量的修改
一个不在局部作用域里的变量默认是只读的,如果试图为其绑定一个新的值,python认为是在当前的局部作用域里创建一个新的变量,也就是说在当前局部作用域中,如果直接使用外部作用域的变量,那么这个变量是只读的,不能修改,如:
count = 10
def outer():
print(count)
count = 100
print(count)
#UnboundLocalError: local variable 'count' referenced before assignment
这里第一个print中,使用到了外部作用域的count,这样后面count就指外部作用域中的count了,再修改就会报错。
如果没使用过这个变量,而直接赋值,会认为是新定义的变量,此时会覆盖外部作用域中变量,如:
count = 10
def outer():
count = 100
print(count)
内部作用域中直接声明了count=100,后面使用count都是内部作用域的了。
4、global关键字
当内部作用域想修改外部作用域的变量时,就要用到global和nonlocal关键字了,当修改的变量是在全局作用域(global作用域)上的,就要使用global先声明一下,代码如下:
count = 10
def outer():
global count
print(count)
count = 100
print(count)
5、nonlocal关键字
global关键字声明的变量必须在全局作用域上,不能嵌套作用域上,当要修改嵌套作用域(enclosing作用域,外层非全局作用域)中的变量怎么办呢,这时就需要nonlocal关键字了
def outer():
count = 10
def inner():
nonlocal count
count = 20
print(count)
print(count)
(1)变量查找顺序:LEGB,作用域局部&外层作用域&当前模块中的全局&python内置作用域;
(2)只有模块、类、及函数才能引入新作用域;
(3)对于一个变量,内部作用域先声明就会覆盖外部变量,不声明直接使用,就会使用外部作用域的变量;
(4)内部作用域要修改外部作用域变量的值时,全局变量要使用global关键字,嵌套作用域变量要使用nonlocal关键字。nonlocal是python3新增的关键字,有了这个关键字,就能完美的实现闭包了。
已发表评论数()
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见
正文不准确
标题不准确
排版有问题
主题不准确
没有分页内容
图片无法显示
视频无法显示
与原文不一致}

我要回帖

更多关于 看今日头条怎么赚钱 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信