一、什么是函数?
引入函数:
需求:根据用户输入圆的半径来计算圆的周长
#根据下面给出的圆的半径,计算圆的周长 r1=12.3 r2=5
r1=int(input('请输入圆的周长:').strip())
delimeter_circle=2*3.14*r1
print(delimeter_circle)
r2=int(input('请输入圆的周长:').strip())
delimeter_circle2=2*3.14*r2
print(delimeter_circle2)
从上面代码可以看出来,除了输入的圆的半径不一样,实现的功能是一样的,都是为了计算圆的半径,但是代码重复太多,可读性差,那么如何解决?函数
函数是组织好的,可重复使用的,用来实现单一,或复杂功能的代码段。
函数能提高应用的模块性,和代码的重复利用率,增强代码的可读性。python有很多的内置函数,比如print(),len()等。但你也可以自己定义函数
def deliemeter_circle(r):
delimeter_circle = 2 * 3.14 * r
print(delimeter_circle)
deliemeter_circle(5)
二、函数的定义与调用
定义:def 关键词开头,空格之后接函数名称和圆括号(),最后还有一个":"。
def 是固定的,不能变,它是定义函数的关键字。
空格 为了将def关键字和函数名分开
函数名:函数名只能包含字符串、下划线和数字且不能以数字开头。函数名应该见名知意
括号:是必须加的,先别问为啥要有括号,总之加上括号就对了!
注释:每一个函数都应该对功能和参数进行相应的说明,应该写在函数下面第一行。以增强代码的可读性。
函数体:函数中进行一系列的具体操作。
参数:为函数体提供数据。
返回值:当函数执行完毕后,可以给调用者返回数据。
def printInfo(info):
print(info)
return info
# 函数名字printInfo 参数info 函数体:print(info) 返回值:info
函数的调用:就是 函数名() 要记得加上括号。调用上述函数:printInfo()
三、详解函数参数
函数参数的分类:
实际参数:函数调用过程中传入的参数 #1,2就是实际参数
形式参数:函数定义的时候传入的参数 #a,b就是形式参数
def add(a,b):
result=a+b
add(1,2)
下面从实参和形参的角度去研究函数的参数
从实参的角度传参
①:按照位置传入参数:位置参数
def add(a,b):
result=a+b
add(1,2)
②:按照关键字进行传入参数:关键字参数
def add(a,b):
result=a+b
add(a=1,b=2)
③:位置传参和关键字传参混合使用
注意事项:两者混合使用的时候,必须先位置传参,后关键字传参
def add(a,b):
result=a+b
add(1,b=2)
从形参的角度传参
①:按照位置进行传入参数:
def add(a,b):
result=a+b
add(1,2)
②:默认参数:将变化很小的可以设置为默认参数,函数调用时,如果默认参数没有传值,那么会使用默认的值,如果传递了新的值,那么会使用新的
def printInfo(username,male='男'):
print('您的名字是:{},性别是{}'.format(username,male))
printInfo('科比') # 您的名字是:科比,性别是男
printInfo('孙二娘','女') #您的名字是:孙二娘,性别是女
关于函数的默认参数的问题:
如果一个函数的默认参数是可变的数据类型,在每一次函数进行调用的时候,如果不传递参数那么这个参数就是共有的资源
def func(i,list=[]):
list.append(i)
return list;
print(func(1))
print(func(2))
print(func(3))
print(func(4))
'''
运行结果:
[1]
[1, 2]
[1, 2, 3]
[1, 2, 3, 4]
'''
③:可接收所有的位置参数与关键字参数:动态参数。
动态参数有两种:
①:args : 接收的是按照位置传参的值,组织成一个元组
def func(*args): #站在形参的角度上,给变量加上*,就是组合所有传来的值。
print(args)
func('str',2,3,4) #('str', 2, 3, 4)
func(*[1,2,3,4,5,6]) #(1, 2, 3, 4, 5, 6) #站在实参的角度上,给一个序列加上*,就是将这个序列按照顺序打散
②:**kwargs: 接受的是按照关键字传参的值,组织成一个字典
def func(**kwargs):
print(kwargs)
func(a=1,b=2,c=3) #{'a': 1, 'b': 2, 'c': 3}
③:接收任意类型的参数
args必须在kwargs之前
def func(*args,**kwargs):
print(args,kwargs)
func('str',1,2,3,[1,2,3,4,5],a=1,b=2,c=3) #('str', 1, 2, 3, [1, 2, 3, 4, 5]) {'a': 1, 'b': 2, 'c': 3}
四、函数的返回值
(1):没有返回值
①:直接return
def add(a,b):
result=a+b
return
②:显示的调用return None(不常用,不推荐使用)
def add(a,b):
result=a+b
return None
③:默认返回None
(2):只有一个返回值
def add(a,b):
result=a+b
return result
res=add(1,2)
print(res) #3
(3):有多个返回值,多个返回值可以使用多个参数进行接收,也可以使用一个参数接收,使用一个参数接收的时候将返回一个元组
def add(a,b):
return a,b
num=add(3,4)
num1,num2=add(3,4)
print(num1,num2)# 3 4
print(num) #(3,4)
四、函数的其他事儿
①:函数可以做参数进行传递
import os
from urllib.request import urlopen
def wrapper(func):
def inner(*args,**kwargs):
if os.path.getsize('cache_web.txt'):
with open('cache_web.txt',mode='rb')as f:
return f.read()
result = func(*args,**kwargs)
with open('cache_web.txt',mode='wb') as f:
f.write(b'******'+result)
return result
return inner
@wrapper
def getContent(url):
code=urlopen(url).read()
return code
res=getContent('http://www.baidu.com')
print(res)
res=getContent('http://www.baidu.com')
print(res)
View Code
②:函数名 执行的是函数的内存地址空间
def func():
print('hello python')
print(func) #<function func at 0x00000124BD053EA0>
③:global 和nolocal的使用
对于不可变数据类型,在局部作用域中可以查看全局作用域中的变量但是不能直接修改,如果想要修改全局作用域中的值,需要在程序的一开始添加global声明,如果在一个局部(函数)内声明了一个global变量,那么这个变量在局部的所有操作将对全局的变量有效;
a='hello world'
def func():
global a
a='hello python'
return a
result=func()
print(result) #hello python
nonlocal关键字用来在函数或其他作用域中使用外层(非全局)定义的变量
def countDemo():
i = 0
def inner():
nonlocal i
for k in range(4):
i +=k
return i
return inner
res=countDemo()
print(res())