python学习(第三天)——函数和变量
函数
如果在开发程序时,需要某块代码多次,但是为了提高编写的效率以及代码的重用,所以把具有独立功能的代码块组织为一个小模块,这就是函数
1、函数的说明
在定义下用""写函数的说明文档,用help可以查看,如:
def PrintHello():
"这是函数的文档说明部分,用help调用"
print("hello world!")
PrintHello()
help(PrintHello)
输出:
hello world!
Help on function PrintHello in module __main__:
PrintHello()
这是函数的文档说明部分,用help调用
2、函数的参数
- 如果在定义函数的时候,在小括号中如果有变量,那么也就意味着,这个函数在调用的时候,需要传递数据
- 传参时不仅传递的数据个数相同,且传递的数据与接收时的变量顺序是一一对应的
- 在定义函数时,小括号中的变量,称为形参:只是一种形式
- 传递进去的数就是实参,实参:实际传递的参数,实际传递的数据
def add2num(num1,num2):
sum = num1 + num2
print(sum)
add2num(100,200)
输出:
300
函数参数的缺省参数
调用函数时,缺省参数的值如果没有传入,则被认为是默认
注意:和C++一样,如果有缺省参数必须要放在最后
def test(a,b="中国"):
print(a)
print(b)
#def test2 (a=100,b):
#print(a)
#print(a)
def test3(a,b=10,c=200):
print(a)
print(b)
print(c)
test(11)
test(11,"其他国家")
#test2(11) #test2用法错误
test3(11, c=22)
输出:
11
中国
11
其他国家
11
10
22
函数的不定长参数
基本语法如下:
def functionname([formal_args,] *args, **kwargs):
"函数_文档字符串"
function suite
return [expression]
加了星号(*)的变量args会存放所有未命名的变量参数,args为元组
而加***的变量kwargs会存放字典,即形如key=value的参数, kwargs为字典。
def addAll(a,*b):
result = 0
result +=a
for x in b:#b相当于元组
result += x
return result
def test4(a,*b,**c):
print(a)
print(b)
print(c)
addResult = addAll(1,5,7,9)
print(addResult)
print('-'*20)
test4(1,2,5,8,9,m=31,n=32,h=33)
输出:
22
--------------------
1
(2, 5, 8, 9)
{'m': 31, 'n': 32, 'h': 33}
3、函数的返回值
函数单个返回值
- “返回值",就是程序中函数完成一件事情后,最后给调用者的结果
- 如果这个函数,有
return
,那么就意味着这个函数有一个返回值,此时就是sum的结果,如果这函数没有return,意味着没有返回值 - 如果一个函数有return,即有返回值,往往在调用的那个地方, 需要一个变量来接收即保存这个返回值
def add2num(num1,num2):
sum = num1 + num2
return sum
result = add2sum(100,200)
print(result)
输出:
300
函数多个返回值
- 如果一个函数中有多个return,那么程序只要执行任何一个return,那么剩下所有return都不会被执行"
- return其实是可以返回一个数据,还有一个功能,只要调用了,那么就会立即结束当前的函数
返回多个函数值的两种方式:
1、直接在return后跟上要返回的变量,用逗号隔开,返回的是元组
2、将要返回的多个返回值赋值给一个元组、列表或者字典
def test():
num = 1
name = "hhh"
age = 11
#return num,name,age #方式1
#info = [num,name,age] #方式2
#info = [num,name,age] #方式3
info = {"num":num,"name":name,"age":age} #方式4
return info
A = test()
print(A)
输出:
{'num': 1, 'name': 'hhh', 'age': 11}
4、函数的4种类型
函数根据有没有参数,有没有返回值,可以相互组合,一共有4种
●无参数,无返回值
●无参数,有返回值
●有参数,无返回值
●有参数,有返回值
5、函数的嵌套
如果函数A中,调用了另外一个函数B,那么先把函数B中的任务都执行完毕之后才会回到上次函数A执行的位置
def printLine():
print("-"*30)
def printNumsL ine(n) :
i=0
while i<n:
printLine()
1+=1
num = int(input("请输入要打印的个数:"))
printNumsLine(num)
6、递归函数
一个函数在内部不调用其他函数而是调用自身,则称为递归函数
def test(num):
if num>1:
result = num+test(num-1)
else:
result = 1
return result
result = test(4)
print(result)
输出:
10
变量
局部变量/全局变量
局部变量:函数内定义的变量(只在定义它的函数中有效,出了函数则无效),形参也是局部变量
全局变量:在函数外定义的变量
注意:python中全局变量在函数中修改前要声明,见下例:
num=100
def test1():
#如果在函数中直接修改全局变量,那么会产生异常
#如果真的需要进行修改,那么可以在函数里面进行声明
global num #声明
print (num)
num+= =2
print (num)
def test2():
print (num)
test1( )
test2( )
注意:如果全局变量是可变类型,即 列表或者字典,则可以直接修改
不可变类型要修改必须添加声明global
,但是下面这种情况不是修改全局变量而是定义一个变量
a = 200
def test3():
a = 100
print(a)
test3()
print("-"*20)
print(a)
输出:
100
--------------------
200
注意:如果局部变量和全局变量名字相同,优先使用局部变量
最好在运用全局变量命名时在最前面加一个g_
引用
变量的引用
在python中,值是靠引用来传递来的。我们可以用id()来判所两个变量是否为同一个值的引用。我们可以将id值理解为那块内存的地址标示(贴标签)
注意:该引用不同于C/C++的指针,当值为可变类型时直接改值,当值为不可变类型时直接贴标签(先产生一个值,再把标签贴上去,如上图所示)
可变类型与不可变类型
可变类型,值可以改变:
●列表list
●字典dit
不可变类型,值不可以改变:
●数值类型int, long, bool, float
●字符串str
●元组tuple
spam = [0, 1, 2, 3, 4, 5]
cheese = spam
cheese[1] = "hello"
print(spam)
print(cheese)
输出:
[0, 'hello', 2, 3, 4, 5]
[0, 'hello', 2, 3, 4, 5]
spam = "666"
cheese = spam
print(id(spam),id(cheese))
cheese = "hello"#字符串不能改,只能重新贴标签
print(id(spam),id(cheese))
print(spam)
print(cheese)
输出:
2233613264408 2233613264408
2233613264408 2233613264576
666
hello
书面解释:
-
python不允许程序员选择采用传值还是传引用。Python参数传递采用的肯定是“传对象引用”的方式。实际上,这种方式相当于传值和传引用的一种综合。如果函数收到的是一个可变对象(比如字典或者列表)的引用,就能修改对象的原始值——相当于通过“传引用”来传递对象。如果函数收到的是一个不可变对象(比如数字、字符或者元组)的引用,就不能直接修改原始对象——相当于通过“传值’来传递对象。
-
当人们复制列表或字典时,就复制了对象列表的引用同,如果改变引用的值,则修改了原始的参数。
-
为了简化内存管理,Python通过引用计数机制实现自动垃圾回收功能,Python中的每个对象都有一个引用计数,用来计数该对象在不同场所分别被引用了多少次。每当引用一次Python对象,相应的引用计数就增1,每当消毁一次Python对象,则相应的引用就减1,只有当引用计数为零时,才真正从内存中删除Python对象。
引用参考:https://www.cnblogs.com/yuyan/archive/2012/04/21/2461673.html
函数传参时的引用
def test1(numsTemp):
numsTemp.append(44)
print(numsTemp)
def test2(numTemp):
numTemp+=1
print(numTemp)
nums = [11,22,33]
a = 100
test1(nums)
test2(a)
print(nums)
print(a)
输出:
[11, 22, 33, 44]
101
[11, 22, 33, 44]
100
列表和数组可变,其它不可变,这里需要注意一下a+=a和a=a+a的区别
def test1(a):
a += a #此种方法变量为可变类型,形参可变
print(a)
def test2(b):
b = b+b #此种方法不论变量是否为可变类型,形参都不可变(即先定义一个变量然后修改)
print(b)
num1=2
num2=[1,2,3]
test1(num1)
test2(num1)
print(num1)
print("=============")
test1(num2)
test2(num2)
print(num2)
输出:
4
4
2
=============
[1, 2, 3, 1, 2, 3]
[1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3]
[1, 2, 3, 1, 2, 3]