文章对关于函数的所有知识进行了详细的总结和讨论,希望可以给大家带来帮助
首先是最简单的函数定义问题(后面附有代码的执行结果)
def myfunction(name):
for i in range(3):
print(f"I love my {name}!")
# myfunction(123)
print("\n")
下面是函数的健壮性和对于返回值的讨论
def div(x,y):
if y == 0:
return "除数不能为0"
return x / y # 函数的返回值,使用return语句
# print(div(2,0))
# 如果函数没有被显示地返回一个返回值,则函数也会返回一个none值
print("\n")
函数的传入参数是有严格的对应关系的,否则输出结果就会让你意想不到
def myfunc(s,vt,o):
return "".join((o,vt,s))
print(myfunc("我","打了","我爸"))
print(myfunc("我爸","打了","我"))
# 要注意函数形参和输出参数的位置一一对应关系
# 使用关键字参数
print(myfunc(o = "我",vt = "打了",s = "我爸"))
# 且普通的参数必须写在关键字参数之前
print("\n")
在未初始化的情况下可使用默认参数
def myfunc2(name1,name2 = "kk"):
return "".join((name1,name2))
print(myfunc2("jj"))
print("\n")
补充一个冷门的知识点,“*”号左边是位置参数(即普通参数),
也可以是关键字参数,但它的右边一定要关键字参数
def abc(a,*,b,c):
print(a,b,c)
print("\n")
下面是关于参数的收集功能的实例
def parameter(*argument):
print("total number is {}".format(len(argument)))
print("the first word is {}".format(argument[0]))
print(argument)
parameter("我","叫","大沙比")
# 收集参数,其中的内部实现是通过元组来实现
# 利用的是元组的打包和解包的功能
print("\n")
注意这种函数写法的时候,对于a b的定义要显示地使用关键字参数
否则输入都会被归纳为前面的args元组中,函数自然就会报错了
def myfunc3(*args,a,b):
print(args,a,b)
myfunc3(1,2,3,a = 4,b = 5)
print("\n")
可以使用字典的写法建立键值对
def myfunc4(**args):
print(args)
myfunc4(a = 1,b = 2,c = 3)
print("\n")
对于上面的的写法,有正向使用就有反向使用
def myfunc5(a,b,c,d):
print(a,b,c,d)
kwargs = {'a':1,'b':2,'c':3,'d':4}
myfunc5(**kwargs)
print("\n")
x = 880
def myfunc6():
global x
x = 660
print(x)
myfunc6()
print(x)
# 如果想打印外面的x,使用global,可以看到函数外面的x值被永久改变了
print("\n")
def funcA():
x = 520
def funcB():
x = 880
print("in funcB,x = ",x)
funcB()
# return funcB # 返回函数时,只需要返回其函数名即可
print("in funcA,x = ",x)
funcA() # 可以注意一下nonlocal的使用,可用之修改外层函数的变量
print("\n")
def funA():
x = 880
def funB():
print(x)
return funB
print(funA())
print(funA()())
funny = funA()
print(funny())
print("\n")
def power(exp):
def exp_of(base):
return base ** exp
return exp_of
square = power(2) # 函数相当于使用到一半,会先保存之前输入的参数
cube = power(3)
print(square(2),square(5))
print(cube(2),cube(5))
print("\n")
再看一个例子进行深入的理解
def outer():
x = 0
y = 0
def inner(x1,y1):
nonlocal x,y
x += x1
y += y1
print(f"现在,x = {x},y = {y}")
return inner
move = outer()
print(move(1,2))
print(move(-2,2))
print("\n")
总结一下就是
1.利用嵌套函数的外层作用域具有记忆能力的特性
2.将内层函数作为返回值给返回
函数名作为另一个函数的参数
import time
def time_master(func):
print("开始运行程序")
start = time.time()
func()
end = time.time()
print("结束程序运行")
print(f"一共耗费的时间为{(end-start):.2f}秒")
def myfunc7():
time.sleep(2)
print("hello!")
time_master(myfunc7)
print("\n")
# 或者用装饰器的方法:核心是 函数当参数+闭包
def time_master2(func):
def call_func():
print("开始运行程序")
start = time.time()
func()
end = time.time()
print("结束程序运行")
print(f"一共耗费的时间为{(end - start):.2f}秒")
return call_func # 注意只返回的是函数名,不需要带括号
@time_master2
def myfunc8():
time.sleep(2)
print("hello!")
myfunc8()
print("\n")
# 可以看到结果和上一个程序的写法是一样的
def add2(func):
def inner():
x = func()
return x + 1
return inner
def cube2(func):
def inner():
x = func()
return x * x * x
return inner
def square2(func):
def inner():
x = func()
return x * x
return inner
@add2
@cube2
@square2
def test():
return 2
print(test())
print("\n")
多层嵌套函数时的装饰器,并给其传递参数
def llogger(msg):
def time_master(func):
def call_func():
start = time.time()
func()
stop = time.time()
print(f"{msg} consums totally {(stop - start):.2f}")
return call_func
return time_master
@llogger(msg="A")
def func9():
time.sleep(1)
print("A is running...")
@llogger(msg="B")
def func10():
time.sleep(1)
print("B is running...")
func9()
func10()
print("\n")
一行流,lambda表达式
语法:lambda arg1,arg2,arg3,…,argN:expression
冒号左边是函数参数,冒号右边是函数表达式和返回值
首先写出普通函数的用法
def squareX(x):
return x * x
print(squareX(3))
# 再用lambda表达式的写法
squareY = lambda y : y * y
print(squareY(3))
print(("\n"))
# lambda也可以用在列表中
y = [lambda x : x * x,2,3]
y[0](y[1])
每调用一次就提供一次数据,并且能记住之前的状态
在之前的状态下继续执行下去
def counter():
i = 0
while i <= 5:
yield i # 产出的的意思,这里产出i
i += 1
print(counter())
for i in counter():
print(i,end=" ") # 取消换行
print("\n")
这是一个递归的阶层函数,程序运行的结果是120
def jieceng(n):
if n > 1:
return n * jieceng(n-1)
else:
return 1
print(jieceng(5),"\n")
接下来是汉诺塔问题
def hanoi(n,x,y,z):
if n == 1:
print(x,"-->",z) # 如果只有1层,直接将金片从x移动到z
else:
hanoi(n-1,x,z,y) # 将x上的n-1个金片从x移动到y
print(x,"-->",z) # 将最底下的金片从x移动到z
hanoi(n-1,y,x,z) # 将y上的n-1个金片移动到z
n = int(input("请输入金片的片数:"))
hanoi(n,'A','B','C')
函数文档 help + 函数 即help(function)
写函数的时候,记得写函数的说明,形式如下
'''
功能:******
参数:******
返回值:******
'''
def times(s:str,n:int) -> str:
return str * n
冒号后面的str和int只是类型注释,表示希望输入的参数的类型
内省(注意使用面向对象的方法调用)
查看函数名 __name__
查看内容 __annotations__
查看函数文档__doc__
import functools
比如 reduce,partial(偏函数)等
wraps(func) 装饰器的进阶