Python函数与变量作用域

来源:互联网 发布:网易上海房产成交数据 编辑:程序博客网 时间:2024/05/29 07:08

函数与变量作用域

一、函数

1.1 函数定义

def 函数名([参数1][,参数2][,参数3]...):  [函数语句]#函数语句和return语句不能同时省略  [return [返回值]]#return后面可以没有返回值

1.2函数调用

在Python中,所有语句都是实时执行的,不存在C/C++的编译过程,def也是一条可执行语句,定义一个函数。所以函数的调用必须在定义之后

>>> def add(a,b):...   return a+b...>>> add<function add at 0x0000000005DAB730>>>> add(1,2)3>>> x=add>>> x(1,2)3>>> def nullFun(a,b):...   return...>>> nullFun(1,2)>>> 

1.3 函数参数

调用函数时,参数表中提供的参数成为实际参数,简称实参。在Python中,变量保存的是对象的引用,类似于C/C++中的指针。实参传递给形参就是将对象引用赋值给形参。

函数的多态性

多态是面向对象的一个特点,指同一个行为针对不同对象可能会得到不同的结果。Python中的对象无类型属性,变量可饮用各种不同类型的对象。同一个函数,传递的实际参数类型不同时,可获得不同的结果,体现了多态性。例如:

>>> def add(a,b):...   return a+b...>>> add(1,3)4>>> add(1,1.5)2.5>>> add('abc', 'def')'abcdef'>>> add([1,3],[2,4])[1, 3, 2, 4]

参数赋值传递

Python允许以形参赋值的方式,指定将实参传递给形参。例如:

>>> def add(a,b):return a+b...>>> add(a='ab',b='cd')'abcd'>>> add(b='ab',a='cd')'cdab'

可以看出,采用这种方式时,以形参赋值为准,参数顺序可以忽略。

参数传递与共享引用

>>> def f(x): x=100...>>> a=10>>> f(a)>>> a10

可以看出在函数中重新赋值a,并不会影响函数外的a,因为Python中的赋值时建立变量到对象的引用。重新赋值时,意味着形参引用了新的对象,原来的引用已经作废。

小心使用可变参数

>>> def f(a):...   a[0]='abc'...>>> x=[1,2]>>> f(x)>>> x['abc', 2]

当使用可变参数时,如列表、字典等,若在函数中修改形参,因为是共享引用,通过实参也获得修改后的对象。如上。

如果不希望在函数中的修改影响函数外的变量,也可以显示的避免。

例如列表,可以使用列表的拷贝作为实参。如:

>>> def f(a):...   a[0]='abc'...>>> x=[1,2]>>> f(x[:])>>> x[1, 2]

也可以在函数内对列表进行拷贝,实参仍使用变量。例如

>>> def f(a):...   a=a[:]...>>> def f(a):...   a=a[:]...   a[0]='abc'...>>> x=[1,2]>>> f(x)>>> x[1, 2]

有默认值的参数

如c++

传递任意个数的参数

定义参数时,参数名前使用“*”,表示可以接受任意个参数(包括0个),这些参数保存在一个元组中。

>>> def add(a,*b,c):...   print(c)...   s=a...   for x in  b:...     s+=x...   return s...>>> add(1,2)3>>> add(1,2,3)6>>> add(1)1

如果带“*”参数的后面仍然有参数,则必须通过赋值传递。如上。

函数嵌套定义

内部定义的函数作用域为函数内

>>> def add(a,b):...   def getsum(x):...     s=0...     for n in x:...       s+=ord(n)...     return s...   return getsum(a)+getsum(b)...>>> add('12', '34')202

lambda函数

lambda函数也成为表达式函数,用于定义一个匿名函数,可以将该函数赋值给变量,通过变量调用。lambda函数定义的基本格式如下。

lambda 参数:表达式

如:

>>> add=lambda a,b:a+b>>> add(1,2)3>>> add('ab','cd')'abcd'

递归函数

如C/C++

函数列表

Python允许将函数作为列表对象,然后列表索引来调用函数。如:

>>> add=lambda a,b:a+b #通过lambda简历>>> add(1,2)3>>> add('ab','cd')'abcd'>>>>>>>>> d=[lambda a,b:a+b,lambda a,b:a*b]>>> d[0](1,3)4>>> d[1](1,3)3>>>>>>#通过def建立>>> def add(a,b):...   return a+b...>>> def fac(n):...   if n==0:...     return 1...   else:...     return n*fac(n-1)...>>> d=[add,fac]#建立包含函数列表的列表对象>>> d[0](1,2)3>>> d[1](5)120>>> d=(add,fac)#建立包含函数列表的元组对象>>> d[0](2,3)5>>> d[1](5)120

提示:函数列表的实质就是在元组、列表和字典等序列中简历函数对象的引用,然后通过索引来调用函数。

二、变量作用域

2.1 作用域类型

变量作用域就是变量的可访问范围,也可称为命名空间。在第一次给变量赋值时,Python创建变量,第一次给变量赋值的位置决定了变量的作用域。

作用域由大到小分为:内置作用域>文件作用域>函数嵌套作用域>本地作用域

本地作用域:不包含其他函数定义的函数的内部成为本地作用于。函数内通过赋值创建的变量,函数参数都属于本地作用域

函数嵌套作用域:包含了其他函数定义的函数的内部成为函数嵌套作用域

文件作用域:程序文件(也称模块文件)的内部为文件作用域

内置作用域:最顶层,包含了python各种预定义变量和函数的作用域成为内置作用域。

内置作用域和文件作用域有时都被成为全局作用域(变量称为全局变量),函数嵌套作用域优势也成为本地作用域(变量成为本地变量)。

作用域外的变量与作用域内的变量名称相同时,遵循“本地”优先原则,此时外部的作用域被屏蔽--成为作用隔离原则。与C/C++类似。但与C/C++不同的是,在更小作用域整体里,定义该重复变量之前的范围,程序是检测不到那个大作用域的变量的。

>>> a=10>>> def show():...   print('a=',a)...   a=100...   print('a=',a)...>>> show()Traceback (most recent call last):  File "<stdin>", line 1, in <module>  File "<stdin>", line 2, in showUnboundLocalError: local variable 'a' referenced before assignment

2.2 global语句

使用global语句可以在函数内部声明全局变量。全局变量增大了代码维护调试难度,不建议用。

>>> a=10>>> def show():...   global a#有用吗?前面不是定义了个全局的a吗?...   a+=1...   print('a=',a)...>>> show()a= 11>>> show()a= 12>>> show()a= 13

2.3 nonlocal语句

作用域隔离原则同样适用于函数内部的嵌套函数。在嵌套函数内使用与上层函数本地变量同名的变量时,若该变量没有被赋值,则该变量就是上层函数的本地变量。如:

>>> def test():...   a=10...   def show():...     print('in show(),a=',a)...   show()...   print('in test(),a=',a)...>>> test()in show(),a= 10in test(),a= 10

稍微修改

>>> def test():...   a=10...   def show():...     a=100...     print('in show(),a=',a)...   show()...   print('in test(),a=',a)...>>> test()in show(),a= 100in test(),a= 100

若想这个a与上一层a为同一个,则需要加一句nonlocal a,来声明变量是外部的本地变量。

>>> def test():...   a=10...   def show():...     nonlocal a...     a=100...     print('in show(),a=',a)...   show()...   print('in test(),a=',a)...>>> test()in show(),a= 100in test(),a= 100

阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 利润公式 未分配利润 息税前利润 营业利润 利润总额 眼镜利润 利润表模板 分配利润 汉堡店利润 本年利润 利润意思 肠粉利润 汉堡利润 水果利润 怎么算利润 利润是什么 利润计算 什么是利润 利润英文 茶叶店利润 利润高 利润大 内衣店利润 卖酒的利润 会计利润是利润总额吗 粥屋利润 零食店利润 经济利润与会计利润 利润分析 纸箱厂利润 会计利润 米粉店利润 利润点 加油站利润 饭店的利润 餐饮利润 微商的利润 酒的利润 卖粥的利润 成本利润 餐饮业利润