def 函数名([形参1,形参2,形参3....]):
代码块
注意:
函数名必须符合标识符的规范(可以包含字母、数字、下划线但是不能以数字开头)
print是函数对象 print()是调用函数
形参(形式参数) 定义形参就相当于在函数内部声明了变量,但是并不是赋值
实参(实际参数)指定了形参,那么在调用函数时必须传递实参,实参将会赋值给对应的形参,简单来说有几个形参就要有几个实参
def fn(name,age=18):
print(f"my name is {name},今年{age}岁了".format(name,age))
fn("小明",20)
def fn(name,age=18):
print(f"my name is {name},今年{age}岁了".format(name,age))
fn("小明")
# my name is 小明,今年18岁了
位置参数:位置参数就是将对应位置的实参赋值给对应位置的形参
关键字参数 : 关键字参数可以不按照形参定义的顺序去传递,而根据参数名进行传递
def fn(name,age=18):
print(f"my name is {name},今年{age}岁了".format(name,age))
fn(age=20,name="小花")
# my name is 小花,今年20岁了
def fn(name,love="花",age=18):
print(f"my name is {name},今年{age}岁了,喜欢{love}".format(name,age))
fn("小花","帅锅",age=20)
#my name is 小花,今年20岁了,喜欢帅锅
在定义函数的时候,可以在形参的前面加上一个*。这样这个形参就可以获取到所有的实参
它将获取到的实参放到一个元组当中*a 会接受所有位置实参,并且会统一保存到一个元组当中
def s(*args):
# 定义一个变量,保存结果
r = 0
# 遍历元祖,将元组中的数进行相加
for n in args:
r += n
print(r)
s(1,2,6,9)
def fn2(a,*b,*c):
^
SyntaxError: invalid syntax
def fn2(a,b,*c):
print('a =',a)
print('b =',b)
print('c =',c)
fn2(1,2,3,4,5)
# a = 1
# b = 2
# c = (3, 4, 5)
def fn2(a,*b,c):
print('a =',a)
print('b =',b)
print('c =',c)
fn2(1,2,3,4,c = 5)
# a = 1
# b = (2, 3, 4)
# c = 5
def fn2(*,a,b,c):
print('a =',a)
print('b =',b)
print('c =',c)
fn2(a = 3,b = 4,c = 5)
a = 3
# b = 4
# c = 5
**形参可以接收其他关键字参数,它会将这些参数统一保存到一个字典当中。
key就是参数的名字,字典的value就是参数的值
**形参只能有一个,并且只能写在所有参数的后面
def fn4(b,c,**a):
print('a =',a)
print('b =',b)
print('c =',c)
fn4(1,2,d=4,e=5)
a = {'d': 4, 'e': 5}
# b = 1
# c = 2
基本原则是:先位置参数,默认参数,包裹位置,包裹关键字(定义和调用都应遵循)
def func(name, age, sex=1, *args, **kargs):
print( name, age, sex, args, kargs)
def s(*args):
# 定义一个变量,保存结果
r = 0
# 遍历元祖,将元组中的数进行相加
for n in args:
r += n # r = r + n
# print(r)
return r
r = s(1,2,6,9)
print(r - 10)
全局作用域在程序执行时创建,在程序执行结束时销毁
函数作用域在函数调用时创建,在调用结束时销毁
def fun():
global c
c =0
fun()
print(c)
a = 0
b = 0
def fun():
global a # 在a 之前添加 global
a = 2
b = 2
fun()
print(a)
print(b)
# 10! = 10 * 9!
# 9!= 9 * 8!
# 8! = 8 * 7!
# ....
# 1! = 1
代码
创建一个函数用递归的方式来解决 求任意数的阶乘
def fn1(n):
# 参数n 要求阶乘的数字
# 1 基线条件
# 判断如果n为1的时候,就是它本身就不需要递归了
if n == 1:
return 1
# 2 递归条件8 * 7!
return n * fn1(n-1)
print(fn1(10))
问题2:定义一个函数 来为任意数字做任意幂运算
分析:
# 10 ** 5 = 10 * 10 ** 4
# 10 ** 4 = 10 * 10 ** 3
# .....
# 10 ** 1 = 10
代码
def fn2(n,i):
# 参数n 要做幂运算的数字
# 参数i 要做幂运算的次数
# 1 基线条件
if i == 1:
return n
# 2 递归条件 10 ** 5 = 10 * 10 ** 4
return n * fn2(n,i-1)
print(fn2(5,6))
print(5 ** 6)
lst = [1,2,3,4,5,6,7,8,9,10]
# 定义一个函数 实现偶数
def fn2(i):
if i % 2 == 0:
return True
# 定义一个函数,将指定列表中的所有的偶数,保存到一个新的列表
def fn(func,l):
# 参数func:需要传递一个函数对象,其实这个函数对象就是我们想要的一个规则
# 参数l:要进行筛选的列表
# 创建一个新的列表
new_lst = []
# 对列表进行遍历在筛选
for n in l:
# 判断n的奇偶
if func(n):
new_lst.append(n)
# 返回新的列表
return new_lst
print(fn(fn2,lst))
匿名函数 lambda表达式
lambda函数表达式可以用来创建一些简单的函数,它是函数的另一种创建方式
语法 lambda 参数列表 : 返回值
定义一个函数 实现2个数的和
def fn(a,b):
return a + b
print(fn(1,2))
print(lambda a,b : a + b)
def waihanshu():
def neihanshu():
print('内函数调用了')
neihanshu() #内部函数需要在调用,要不只调用外部函数的功能
print('我是外函数')
waihanshu()
# 内函数调用了
# 我是外函数
注意:不能在 外面单独的调用其内嵌函数
闭包的好处
通过闭包可以创建一些只有当前函数能访问的变量
可以将一些私有数据藏到闭包中
行成闭包的条件:
函数嵌套
将内部函数作为返回值返回
内部函数必须要使用到外部函数的变量
>>> def fun():
... a = 1
... def fun1():
... return a
... return fun1
...
>>> f = fun()
>>> print(f())
1
在函数 fun() 里面,有 a = 1 和 函数 fun1() ,它们两个都在函数 fun() 的环境里面,但是它们两个是互不干扰的,所以 a 相对于 fun1() 来说是自由变量,并且在函数 fun1() 中应用了这个自由变量 – 这个fun1() 就是我们所定义的闭包。闭包实际上就是一个函数,但是这个函数要具有 1.定义在另外一个函数里面(嵌套函数);2.引用其所在环境的自由变量。上述例子通过闭包在 fun() 执行完毕时,a = 1依然可以在 f() 中,即 fun1() 函数中存在,并没有被收回,所以 print(f()) 才得到了结果
>>> def fun(a,b,c):
... def para(x):
... return a*x**2 + b*x + c
... return para
...
>>> f = fun(1,2,3)
>>> print(f(2))
11
上面的函数中,f = fun(1,2,3) 定义了一个一元二次函数的函数对象,x^2 + 2x + 3,如果要计算 x = 2 ,
该一元二次函数的值,只需要计算 f(2) 即可
import time
def count_time(f):
#f指的是要装饰的函数,
def call_fun(*args,**kwargs):
#因为不确定要输入什么类型的参数,所以用*args,**kwargs表示形参
print("开始计算")
t1 = time.time()
time.sleep(2)
f(*args,**kwargs)
t2 = time.time()
t = t2-t1
print("一共用时{0}".format(t))
print("结束计算")
#最后返回函数,实现闭包功能,即可以在函数外部,调用内部函数
return call_fun
@count_time#装修函数,此行代码等同于yunsuan =count_time(yunsuan),可看代码3分析
def yunsuan(a,b):
s=a+b
# print(s)
return s
s = yunsuan(8,5)
print(s)
开始计算
一共用时2.0007264614105225
结束计算
None
结果发现返回值为None,原因是在装修器内没有返回值,可定义一个参数结束函数返回值,并return一下
代码改后如下:
import time
def get_time(f):
#f指的是要装饰的函数,
def call_fun(*args,**kwargs):
#因为不确定要输入什么类型的参数,所以用*args,**kwargs表示形参
print("开始计算")
t1 = time.time()
time.sleep(2)
r=f(*args,**kwargs)#调用要修饰的函数,并接受返回值
t2 = time.time()
t = t2-t1
print("一共用时{0}".format(t))
print("结束计算")
return r#不要忘了返回
return call_fun#最后返回函数,实现闭包功能,即可以在函数外部,调用内部函数
@get_time#装修函数,此行代码等同于yunsuan =count_time(yunsuan),可看代码3分析
def yunsuan(a,b):
s=a+b
# print(s)
return s
s = yunsuan(8,5)
print(s)
代码3:不使用装饰器
import time
def count_time(f):
def call_fun(*args,**kwargs):
print("开始计算")
t1 = time.time()
time.sleep(2)
r = f(*args,**kwargs)
t2 = time.time()
t = t2-t1
print("一共用时{0}".format(t))
print("结束计算")
return r
return call_fun
def yunsuan(a,b):
s=a+b
# print(s)
return s
#***********************************************************
yunsuan =count_time(yunsuan)
s = yunsuan(8,5)
print(s)
总结步骤:
#第一步
def fn1(f):
#f指的是要装饰的函数,
def call_fun(*args,**kwargs):
#因为不确定要输入什么类型的参数,所以用*args,**kwargs表示形参
#此处可以添加需要扩展功能代码,,,,,,,,,
r=f(*args,**kwargs)#调用要修饰的函数,并接受返回值
#此处可以添加需要扩展功能代码,,,,,,,,,
return r#不要忘了返回
return call_fun#最后返回函数,实现闭包功能,及可以在函数外部,调用内部函数
#第二步
@fn1#装修函数
def fn2(*args,**kwargs):
#代码功能
return “需要返回的数据”
#第三步
#调用函数
参考代码
参考代码2
推荐b站视频讲解
实际上没有太大价值
# locals()来获取当前作用域的命名空间 返回的是一个字典
a = 10
def fn():
print('我是函数fn....')
scope = locals()
print(scope)