- 一、函数基础
- 函数概念:
- 调用函数语法
- 二、函数参数
- 参数传递
- 值传递
- 引用传递
- 必备参数
- 关键字参数
- 缺省参数
- 不定长参数
- 三、变量作用域
- 作用域的类型
- 变量名解析LEGB法则
函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。函数能提高应用的模块性和代码的重复利用率,可以被用户调用
定义函数语法:
def function(params):
block;
return expression/value;
1.在Python中采用def关键字进行函数的定义,不用指定返回值的类型
2.函数参数params可以是零个、一个或者多个,同样的,函数参数也不用指定参数类型,因为在Python中变量都是弱类型的,Python会自动根据值来维护其类型
3.return语句是可选的,它可以在函数体内任何地方出现,表示函数调用执行到此结束;如果没有return语句,会自动返回NONE,如果有return语句,但是return后面没有接表达式或者值的话也是返回NONE
调用函数语法函数名(参数表) 函数举例:
def Hello():
print('hello');
def Num():
for i in range(0,10):
print(i);
return;
Hello();
Num();
二、函数参数
函数参数分为:形参和实参
形参:全称是形式参数,在用def关键字定义函数时函数名后面括号里的变量称作为形式参数
实参:全称为实际参数,在调用函数时提供的值或者变量称作为实际参数。
例如:
def add(a,b): #a和b为形参
'''add函数实现加法功能'''
return a+b;
c=add(2,3); #2和3为实参
print (c);
备注: python中在定义方法之后可以加上一段字符串,对函数功能进行说明,符号:“”“说明内容”“” 或者 ‘’‘说明内容’‘’
参数传递在 python 中,类型属于对象,变量是没有类型的:
str = "newdream";
str = 100;
在以上代码中,newdream 是string类型的,100是整型,而变量str是没有类型的,它仅 仅是一个对象的引用(指针),可以指向各种类型对象
python 函数的参数传递: 不可变类型:整数、字符串、元组。如fun(num),传递的只是num的值,没有影响num对象本身,如果在 fun(num)内部修改 num 的值,只是修改另一个复制的对象,不会影响 num本身
可变类型:列表,字典,如 fun(listc),则是将 listc真正的传过去,修改后fun外部的listc也会受影响
值传递def changenum(numa):
numa = 20;
numb = 10;
changenum(numb);
print(numb);
引用传递
def changeme( mylist ):
'''修改传入的列表'''
mylist.append([100,200,300]);
print("函数内取值:", mylist);
return;
mylist = [20,40];
changeme(mylist);
print ("函数外取值:", mylist);
Python函数参数类型: 必备参数、关键字参数、缺省参数、任意个数参数
必备参数必备参数须以正确的顺序传入函数,也叫做位置参数,即参数是通过位置进行匹配的,从左到右,依次进行匹配,这个对参数的位置和个数都有严格的要求
例如:
def tme( str ):
print(str);
return;
tme('newdream'); #函数调用
关键字参数
关键字参数函数调用关系紧密,调用方用参数的命名确定传入的参数值。你可以跳过不传的参数或者乱序传参,因为Python解释器能够用参数名匹配参数值
def tme2( str ):
print(str);
return;
tme2(str = "My string"); #函数调用函
缺省参数
调用函数时,缺省参数的值如果没有传入,则被认为是默认值。
def info1(name, age = 35 ):
print ("Name: ", name);
print ("Age ", age);
return
info1(age=50, name="miki");
info1(name="miki");
使用默认参数有一点要非常注意,在重复调用函数时默认形参会继承之前一次调用结束之后该形参的值
def insert(a,L=[]):
L.append(a);
print(L);
insert('hello');
insert('world');
不定长参数
不定长参数(收集参数)当需要一个函数能处理比当初声明时更多的参数。这些参数叫做不定长参数也叫收集参数
def info2( arg1, *vartuple ):
print ("输出: ");
print (arg1);
for var in vartuple:
print(var );
return;
info2(10);
info2(70, 60, 50);
‘ * ’ 和 ‘ ** ’ 表示能够接受0到任意多个参数,‘ * ’ 表示将没有匹配非关键字参数都放在同一个元组中,‘ ** ’ 表示将没有匹配关键字参数都放在一个dictionary中,
Python中函数是可以返回多个值的,如果返回多个值,会将多个值放在一个元组或者其他类型的集合中来返回
例如:
def fun_var_args(farg, *args):
print( 'args:', farg);
for value in args:
print ('another arg:',value);
# *args可以当作可容纳多个变量组成的list或tuple
fun_var_args(1, 'two', 3, None);
def fun_var_kwargs(farg, **kwargs):
print ('args:',farg);
for key in kwargs:
print ('another keyword arg:%s:%s' % (key, kwargs[key]));
# myarg1,myarg2和myarg3被视为key, 感觉**kwargs可以当作容纳多个key和value的dictionary
fun_var_kwargs(1, myarg1='two', myarg2=3, myarg3=None);
三、变量作用域
在Python程序中创建、改变、查找变量名时,都是在一个保存变量名的空间中进行,我们称之为命名空间,也被称之为作用域。python的作用域是静态的,在源代码中变量名被赋值的位置决定了该变量能被访问的范围。即Python变量的作用域由变量所在源代码中的位置决定
作用域的类型1.局部作用域在函数内部定义,拥有一个局部作用域,局部变量只能在其被声明的函数内部访问
2.嵌套作用域在函数内部定义,它和局部作用域是相对的,它相对于更上层的函数而言也是属于局部作用域,主要是为了实现Python的闭包,而增加的实现
3.全局作用域在函数外部定义,拥有全局作用域,全局变量可以在整个程序范围内访问。函数内部可以通过global强制定义全局变量,当函数调用时,全局变量生效。全局作用域的作用范围仅限于单个模块文件内
4.内置作用域是系统内固定模块里定义的变量
常用的作用域是局部作用域、全局作用域
变量名解析LEGB法则搜索变量名的优先级:局部作用域 > 嵌套作用域 > 全局作用域 > 内置作用域
LEGB法则: 当在函数中使用未确定的变量名时,Python会按照优先级依次搜索4个作用域,以此来确定该变量名的意义。首先搜索局部作用域(L),之后是上一层嵌套结构中def或lambda函数的嵌套作用域(E),之后是全局作用域(G),最后是内置作用域(B)。按这个查找原则,在第一处找到的地方停止。如果没有找到,则会触发NameError错误
例如:
name="Jims"; #全局变量
def set1():
global name #使用全局变量
name="ringkee";
set1();
print(name);
print(vars()); #查看内置变量
def scopetest():
a = 6; #嵌套局部变量
print(a);
def innerFunc():
a = 10;#局部变量
print(a);
innerFunc();
a = 5;
print(a);
scopetest();
print(var);
