Python基础笔记系列九:变量、自定义函数以及局部变量和全局变量
本系列教程供个人学习笔记使用,如果您要浏览可能需要其它编程语言基础(如C语言),why?因为我写得烂啊,只有我自己看得懂!!
- 变量
在前面的系列中也许就可以发现,python中的变量和C中的变量有些许不同。比如在C中:
例子:1 #include <stdio.h> 2 3 int main(void) 4 { 5 /* code */ 6 int a,b,c; 7 int *p,*q,*t; 8 9 a = 5,b=8,c=5; 10 p = &a; 11 q = &b; 12 t = &c; 13 printf("%d\n",p); 14 printf("%d\n",q); 15 printf("%d\n",t); 16 return 0; 17 }
输出:
1 6487604 2 6487600 3 6487596
从输出结果可以看出,虽然a和c的值是一样的,但是a和c的地址是不同的。也就是说a开始赋值为5开辟了一块空间,当c赋值为5时又会给它分配一块空间。
但是在python 中就不同,如下的例子。
例子:1 #----------变量-------- 2 a = 5 3 b = 8 4 c = 5 5 print id(a) #id(变量名) 用于取变量的地址 6 print id(b) 7 print id(c)
输出:
1 86995552 2 86995516 3 86995552
从上面两个例子中我们可以看出区别:
1)c语言中定义变量需要定义变量类型,具体这个变量是int、long还是char等等,而python中不关心变量的类型,直接定义变量,它会自己寻找最合适的类型进行存储,可通过type(变量名)来查看变量的类型,在前面的系列中也可以看出python的变量没有类型,比如定义一个字符串str则可以直接:str = "hello"。
2)c语言中定义变量时不管内存空间中有没有这个值都会重新开辟一块新的空间,而python中如果在内存空间中存在一个相同的值,就不会开辟新空间,直接将变量指向这块空间。 - 自定义函数
一、函数的定义规则
#1.def定义函数 2.函数后有":"号 3.以代码缩进表示函数体#def 函数名(参数名):
# '注释内容'
# 执行语句
# return
例子1:1 def add(x,y): 2 z = x + y 3 return z 4 5 result = add(3,5) 6 print result
输出:8
例子2:def printName(str): '打印任意传入的参数' print str return
输出:
1 你好,python
二、函数的调用
1.如果函数在于另一个模块中,则需要import导入模块才能调用;
2.如果函数在当前模块中,则可以直接调用。1 #如果函数在单独的一个文件 需要先import 文件名 2 printName('你好,python') #调用函数 3 #比如通过help 查看函数中的注释内容,其实就是使用了python的help函数 4 print help(printName)
三、函数的值传递和引用传递
在此之前要知道函数的参数有两种:形参和实参
形参:在函数定义时的变量成为函数的形参,形参主要用于接收调用方传递过来的值或引用;
实参:函数调用时的实际参数。
函数的值传递也就是实实在在值的传递问题。
例子:1 def function1(var): 2 '按值传递,修改值' 3 var = 100 4 print 'id= ',id(var) 5 print '函数内取值:',var 6 return 7 8 var =5 9 function1(var) #调用函数 10 print 'id= ',id(var) 11 print '函数外取值:',var #
输出:
1 id= 89814444 2 函数内取值: 100 3 id= 89813600 4 函数外取值: 5
函数的引用传递传的是一个引用,如果你在函数里修改了参数,那么在调用这个函数的函数里,原始的参数也改变了。
例子:1 def changeme(mylist): 2 '修改传入的列表' 3 # mylist =[1111,222,333] #重新进行了赋值操作,变为值传递 4 mylist.append([1,2,3,4]) 5 print 'id= ',id(mylist) 6 print '函数内取值:',mylist 7 return 8 9 mylist = [4,5,6,7] 10 changeme(mylist) #调用函数 11 print 'id= ',id(mylist) 12 print '函数外取值:',mylist #
输出:
1 id= 91525568 2 函数内取值: [4, 5, 6, 7, [1, 2, 3, 4]] 3 id= 91525568 4 函数外取值: [4, 5, 6, 7, [1, 2, 3, 4]]
从上面两个例子中可以看出,其实就是说如果在函数里面对传进来的这个变量进行了赋值(就有了不同空间地址),那么函数内部这个变量的值就改变了,而函数外部还是没有变化,这就是值传递。如果函数里面对传进来的那个变量只是在他原本的基础上(同一块地址上)进行操作,那么函数内部这个变量的值就改变了,而函数外部也跟着变化,这就是引用传递。从C语言的角度来说,值传递和或引用传递也就是地址或值的改变。(个人这样认为,如果你有更好的见解欢迎教小弟一把~底部有联系方式)
四、函数的参数类型
python函数的参数类型主要有四种:必备参数、命名参数、缺省参数、不定长参数。
必备参数:调用方必须以正确顺序传入参数,且数量要和声明时的一样;
命名参数:调用方用参数的命名确定传入的参数值
缺省参数:函数的参数可以设置默认值,如果设置了默认值则调用方可以不给它传参而使用默认值
不定长参数:一个函数可以处理比当初声明时更多的参数,这些参数就是不定长参数
例子:1 #1必备参数 2 def printA(a,b): 3 '打印任意传入的参数' 4 print a + b 5 return 6 printA(1,2) #调用函数 7 print '-'*30 8 #2命名参数 9 def printA(a,b): 10 '打印任意传入的参数' 11 print a + b 12 return 13 printA(b=1,a=2) #调用函数 14 print '-'*30 15 #3缺省参数 16 def printB(a,b=5): #设置了默认值 17 '打印任意传入的参数' 18 print 'a=%d'%a 19 print 'b=%d'%b 20 return 21 printB(1) #只传了一个参数,则b使用默认值 22 printB(1,2) #若传了两个参数,则不使用默认值
输出:
1 3 2 ------------------------------ 3 3 4 ------------------------------ 5 a=1 6 b=5 7 a=1 8 b=2
不定长参数是一个函数可以处理比当初声明时更多的参数,不定长参数有两种定义方式。一种是将不定长参数匹配为元组,另一种是将不定长参数匹配为字典。
例子:1 #不定长参数匹配为元组 2 def arglist(a,*b): #不定长参数用*号定义 其本质为一个元组 3 print a 4 print b 5 return 6 arglist(1,2,3,5,6) #第一个匹配a,后面的就是一个元组b 7 8 print '-'*30 9 #不定长参数匹配为字典(key-value) 10 #例1 11 def arglist1(a,**b): #不定长参数用**号定义 其本质为一个字典 12 print a 13 print b 14 return 15 arglist1(1,x=2,y=3) #第一个匹配a,后面的就是一个字典b 16 17 #例2 18 def arglist2(**a): #不定长参数用**号定义 其本质为一个字典 19 print a 20 for key in a: 21 print key+' = '+ str(a[key]) 22 return 23 arglist2(x=2,y=3,z=5) 24 25 print'-'*30
输出:
1 1 2 (2, 3, 5, 6) 3 ------------------------------ 4 1 5 {'y': 3, 'x': 2} 6 {'y': 3, 'x': 2, 'z': 5} 7 y = 3 8 x = 2 9 z = 5
五、函数的return语句
python不同与其它编程语言,它的return语句可以返回多个返回值,返回多个值放在一个元组中。
例子:1 def arglist3(): 2 print 'call this function' 3 return 1,2,3,4,5 4 5 res = arglist3() #调用方法 6 print res #打印返回值(元组) 7 print res[0:3] #同样可以操作这个元组
输出:
1 call this function 2 (1, 2, 3, 4, 5) 3 (1, 2, 3)
六、匿名函数
匿名函数,顾名思义就是没有名字的函数,在python中使用lambda表达式定义。#1.得名于省略了用def声明函数的标准步骤
#2.Lambda函数能接收任何数量的参数但只能返回一个表达式的值
#3.不能包含多个命令和表达式
#4.匿名函数不能直接调用print ,因为lambda需要一个表达式,所以需要一个变量来存表达式的值
#5.lambda函数拥有自己的名字空间,且不能访问自由参数列表之外或全局名字空间里的参数
#6.lambda函数的语法只包含一个语句,例如,函数名=lambda [参数1,参数2,...] :表达式
例子:1 sum = lambda arg1,arg2 : arg1+arg2 2 print sum(5,3) #调用sum函数 3 print type(sum)
输出:
1 8 2 <type 'function'>
-
局部变量和全局变量
一般地,在函数体内部定义的变量是局部变量,只能在函数体内部访问(可以使用global关键字将局部变量定义为全局变量),而不包含于任何一个函数的,或者说是与main函数属于同一级的是全局变量,可以在main函数中任何地方使用(如果要在某函数体内部修改全局变量的值,使用global关键字)。
函数在调用时就会全部解析函数体,如果函数体内有定义和全局变量同名的局部变量,则函数体使用的是局部变量,在定义之前使用则会出错;但是如果整个函数体都没有定义该变量,它可以直接调用全局变量
例子:1 def function1(): 2 #print num1 #在定义之前打印(报错) 3 num1 = 10 4 global num2 5 num2 = 20 6 print num1 7 num1=5 8 function1() 9 print num1 10 print num2 #调用全局变量num2
输出:
1 10 2 5 3 20