函数定义
- 格式
# 格式
# def 函数名(num):
# pass
# 调用函数:
# 函数名(num)
- 函数定义实例:
def caculateNum(num):
"""
计算1~num质检的累加和
:param num:累加和的末尾
:return: 返回累加和
"""
res = 0
for i in range(1,num+1):
res += i
return res
res = caculateNum(100)
print(res)
5050
三种传参方式
- 按位置顺序传参
def get_fullname(first_name,last_name='凌宇'):
full_name = first_name+last_name
return full_name
full_name = get_fullname('李','诗才')
print(full_name)
李诗才
- 按关键字传参,参数顺序可以任意
def get_fullname(first_name,last_name='凌宇'):
full_name = first_name+last_name
return full_name
full_name = get_fullname(last_name='诗才',first_name='李')
print(full_name)
李诗才
- 默认传参
当参数缺省时,默认参数会生效,默认参数需要在函数声明时指定其值,如果传参时省略了默认参数,则该参数的值为默认值。如下函数中的last_name
def get_fullname(first_name,last_name='凌宇'):
full_name = first_name+last_name
return full_name
full_name = get_fullname(first_name='李')
print(full_name)
李凌宇
“*”操作符
将参数放置到一个元组中
def self_print(name,*a):
print(name)
print(type(name))
print(a)
print(type(a))
self_print(1,2,3,4,5,6)
1
<class 'int'>
(2, 3, 4, 5, 6)
<class 'tuple'>
1被赋值给了name,后面的2,3,4,5,6放置到元组中
注意:*操作符也可以拆开元组或列表
效果如下:
# * 有拆开元组、列表的作用
t = (1,2,3,4,5)
print(*t)
1 2 3 4 5
所以以上代码可以改成如下:
def self_print(name,*a):
print(name)
print(type(name))
print(a)
print(type(a))
self_print(*(1,2,3,4,5,6))
1
<class 'int'>
(2, 3, 4, 5, 6)
<class 'tuple'>
“**”操作符
把参数都放入到字典中
def d_self_print(**kwars):
print(kwars)
d_self_print(first_name="li",last_name="shicai")
{'first_name': 'li', 'last_name': 'shicai'}
注意:“**”操作符如果作用于字典,可以将一个字典拆开所以上面代码可以和下面这种写法等效
# ** 有拆开字典的作用
def d_self_print(**kwars):
print(kwars)
d_self_print(**{'first_name': 'li', 'last_name': 'shicai'})
{'first_name': 'li', 'last_name': 'shicai'}
return
用于返回值,可以用“,”分割,代表一个元组
def sum_and_avg(*numbers):
total = sum(numbers)
avg_number = total/len(numbers)
return total,avg_number
sum,avg = sum_and_avg(1,2,3,4,5,6,7,8,9,10)
print("总和是%f"%(sum))
print('平均值是%f'%(avg))
总和是55.000000
平均值是5.500000
函数的传参问题
参数分为引用类型,普通类型,python中的基本数据类型都是普通类型。包括数、布尔、字符串型,除了这些之外的都是引用类型。普通类型赋值的时候传的是值;引用类型赋值的时候,传的是址
l1 = [1,2,3,4,5,]
l2 = l1
l2[1] = 5
print(l1)
a = 5
b = a
b = 10
print(a)
[1, 5, 3, 4, 5]
5
上面列表传的是列表的地址,是引用,而b=a的操作是传的值
传参的本质就是赋值操作,如果传递的引用数据类型,则需要注意是否在函数中对其做出了修改
为了防止在函数中修改了值,通常会创建一个数据副本
def power(numbers):
# 列表推导式可以创建一个副本,不改变原本的值,
# 函数中的numbers与外部的number不是同一个number,只是值相同,但地址不同
# numbers = [x**2 for x in numbers]
# 也可以赋值创建副本,不改变原本的值
# numbers = numbers[:]
# numbers = list(numbers)
numbers[3] = 10
return numbers
nums = [1,2,3,4,5,6,7,8,9,10]
print(power(nums))
print(nums)
函数的本质
函数的本质其实是地址
def fun():
print("hello world!")
# 函数名的本质是函数的地址
f = fun
print('f即函数的地址:', f)
f() # 效果等同于fun()
f即函数的地址: <function fun at 0x000001B512E5C1E0>
hello world!
函数的闭包
即函数的嵌套在函数内部还可以定义一个函数,例子包含在下面变量的讲解中。
函数变量的作用域
python中,变量的作用域是以函数为单位的,内层函数可以访问外层函数的变量,但是不能修改
def outter():
a = 10
def inner():
a = 20
print('内层',a)
print('外层未改变',a)
return inner
outter()()
外层未改变 10
内层 20
- global:加了global表示调用的时全局变量,即最外层变量,而不是当前函数或者外层函数所创建的
a = 5
def outter():
a = 10
def inner():
global a # 用了global后,与全局a是同一个,并非副本
print('内层赋值前',a)
a = 20
print('内层赋值后',a)
inner()
print('外层函数的变量不变',a)
outter()
print('最外层全局变量因内层赋值后而改变',a)
内层赋值前 5
内层赋值后 20
外层函数的变量不变 10
最外层全局变量因内层赋值后而改变 20
- nolocal
nolocal修饰变量时,说明使用的嵌套层函数的变量,内层函数访问变量时会先从自己查找,如果找不到,就会层层向上查找
a = 5
def outter():
a = 10
def inner():
nonlocal a # 用了global后,与全局a是同一个,并非副本
print('内层赋值前',a)
a = 20
print('内层赋值后',a)
inner()
print('外层函数的变量改变',a)
outter()
print('最外层全局变量不变',a)
内层赋值前 10
内层赋值后 20
外层函数的变量改变 20
最外层全局变量不变 5
总结:变量通常只作用于当前函数体内,若内层函数有同名变量,其实只是外层函数变量的副本,改变内层函数变量的值,并不改变外层函数变量的值;但加了global或nolocal关键字修饰后的变量则不同,内层函数变量不再是副本,用global修饰的内层函数变量就是全局变量,nolocal修饰的变量层层向上查找,改变内层函数变量的值即改变的外层的值。类似于传址。
函数的递归
所谓递归,就是自己调用自己,编写递归函数时,一定要注意出口的设置,否则函数会无线调用下去;并且可以用递归解决的问题一定可以用循环解决。不多说,直接上个阶乘的例子
def factorial(n):
mm = 1
for num in range(1,n+1):
mm *=num
return mm
print(factorial(5))
def factorial1(n):
if n== 1:
return 1
return n * factorial(n-1)
print(factorial1(5))
120
120
高阶函数
函数的参数或返回值是函数的函数,一般函数的参数是另一个函数的地址,看下面代码很好理解
def handle(func, *param):
return func(*param)
def my_sum(*param):
sum = 0
for i in param:
sum += i
return sum
print(my_sum(1,2,3,4,5,6))
# 函数的参数还是一个函数
print(handle(my_sum,1,2,3,4,5,6))
21
21
可能用到的高级函数
- map(func, iterator) 该函数会把可迭代对象中的数据一次传递给func函数处理,最后把处理的结果返回
def power(x):
return x*x
result = map(power,[1,2,3,4,5,6])
print(result)
print(list(result))
[1, 4, 9, 16, 25, 36]
- reduce(func,iterator)
reduce函数累积操作。func函数必须接收两个参数。reduce会把func的运行结果做一个参数,然后从iterator中导入另一个参数,注意,第一次会func会直接从iterator中导入两个参数作为其参数
from functools import reduce
li = [1,2,3,4,5]
result = reduce(lambda x,y:x * y,li)
print(result)
120
filter(func,inteable)
根据func来过滤interable。将interable中的数据传入函数func中如果函数返回True,就保留;否则过滤掉
li = [1,2,4,5,6,9,10,15]
result = list(filter(lambda x: x % 2 == 1,li))
print(result)
[1, 5, 9, 15]
- .doc
可以查看函数的文档随便举两个例子就知道他的用法了
from functools import reduce
print(reduce.__doc__)
print(map.__doc__)
reduce(function, sequence[, initial]) -> value
Apply a function of two arguments cumulatively to the items of a sequence,
from left to right, so as to reduce the sequence to a single value.
For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates
((((1+2)+3)+4)+5). If initial is present, it is placed before the items
of the sequence in the calculation, and serves as a default when the
sequence is empty.
map(func, *iterables) --> map object
Make an iterator that computes the function using arguments from
each of the iterables. Stops when the shortest iterable is exhausted.
网友评论