仅记录个人学习Python所学,学识浅薄,若有错误欢迎指出。文章可能会不太完善,后续可能会继续更新。
一、概述
问题: 代码重复
后期维护成本太高
代码可读性不高
解决问题:函数
在一个完整的项目中,某些功能会被反复使用,那么将这部分功能对应的代码提取出来,当需要使用功能的时候直接使用
本质:对一些特殊功能的封装
优点:
a.简化代码结构,提高应用的效率
b.提高代码复用性
c.提高代码的可读性和可维护性
建议:但凡涉及到功能,都尽量使用函数实现
二、使用函数
语法:
def 函数名(参数1,参数2,参数3…):
函数体
返回值
说明:
a.函数由两部分组成:声明部分和实现部分
b.def,关键字,是define的缩写,表示定义的意思
c.函数名:类似于变量名,遵循标识符的命名规则,尽量做到顾名思义
d.():表示的参数列表的开始和结束
e.参数1,参数2,参数3… :参数列表【形式参数,简称为形参】,其实本质上就是一个变量名,参数列表可以为空
f.函数体:封装的功能的代码
g.返回值:一般用于结束函数,可有可无,如果有返回值,则表示将相关的信息携带出去,携带给调用者,如果没有返回值,则相当于返回None
函数调用
def fn():
print('fn')
# 调用函数
fn()
#注意1:当定义好一个函数之后,这个函数不会自动执行函数体
#2.函数的调用
#格式:函数名(参数列表)
#注意2:当调用函数的时候,参数列表需要和定义函数时候的参数列表保持一致
#注意3:一个函数可以被多次调用
fn()
fn()
#3.注意4:当在同一个py文件中定义多个同名的函数,最终调用函数,调用的最后出现的函数【覆盖:函数名类似于变量名,相当于变量的重新赋值】
#4.注意5:自定义函数必须先定义,然后才调用,否则报NameError
参数
参数列表:如果函数所实现的功能涉及到未知项参与运算,此时就可以将未知项设置为参数
格式:参数1,参数2…
分类:
形式参数:在函数的声明部分,本质就是一个变量,用于接收实际参数的值 【形参】
实际参数:在函数调用部分,实际参与运算的值,用于给形式参数赋值 【实参】
传参:实际参数给形式参数赋值的过程,形式参数 = 实际参数
# 参数:
# 形参:形式参数,在函数声明的括号中 如: a,b
# 实参: 实际参数,在函数调用的括号中 如:2,3
# 求一个年份是否是闰年
def is_leap(year):
if year % 4 == 0 and year % 100 != 0 or year % 400 == 0:
# print(year, '是闰年')
return True
else:
# print(year, '平年')
return False
r = is_leap(2020)
print(r)
返回值 return
作用:表示一个函数执行完毕之后得到的结果
使用:return,表示结束函数,将函数得到的结果返回给调用者
# return 返回
# 1. 终止函数
# 2. 可以返回结果
# 3. 如果没有return或return后没有值,则默认返回None
# 交换两个变量
# return : 多个值
def change(a, b):
return b, a
r = change(1, 2)
print(r) # (2, 1)
参数的类型
必需参数
调用函数的时候必须以正确的顺序传参,传参的时候参数的数量和形参必须保持一致
关键字参数
使用关键字参数允许函数调用的时候实参的顺序和形参的顺序可以不一致,可以使用关键字进行自动的匹配
# 函数参数
# 位置参数/必需参数
def f1(x, y):
print(x, y)
f1(3, 4)
# 默认参数
def f2(x, y, z=1):
print(x, y, z)
f2(3, 4)
f2(3, 4, 6)
# 关键字参数
def f3(x, y=5, z=4):
print(x, y, z)
f3(3)
f3(3, z=6)
# 可变参数/不定长参数
# *args: 用来接收任意多个位置参数,接收一个元组
def f4(*args):
print(args)
f4()
f4(3, 5, 6)
def f5(x, y, *args, z=9, k=10):
print(x, y, args, z, k)
f5(1, 2, 3, 4, 5, 6, 78, z=99, k=0) # 1 2 (3, 4, 5, 6, 78) 99 0
# **kwargs: 用来接收任意多个关键字参数,会得到一个字典
def f6(x, y, **kwargs):
print(x, y, kwargs)
f6(2, 3, z=7, k=10) # 2 3 {'z': 7, 'k': 10}
# 参数的书写顺序:
# 形参:位置参数,*args,默认参数,**kwargs
# 实参: 位置参数,关键字参数
def f7(a, *args, b=3, **kwargs):
print(a, args, b, kwargs)
f7(1) # 1 () 3 {}
f7(1, 2, 3, 4, 5, b=2, z=7, j=9) # 1 (2, 3, 4, 5) 2 {'z': 7, 'j': 9}
# 接收任意参数:通配参数
def f8(*args, **kwargs):
print(args, kwargs)
f8(1, 2, 3, 4, x=5, y=6) # (1, 2, 3, 4) {'x': 5, 'y': 6}
匿名函数
不再使用def这种的形式定义函数,使用lambda来创建匿名函数
特点:
a.lambda只是一个表达式,比普通函数简单
b.lambda一般情况下只会书写一行,包含参数,实现体,返回值
语法:lambda 参数列表 : 实现部分
# 匿名函数: 没有名字的函数
# 普通函数
def f(n):
return n ** 2
# => 匿名函数
f2 = lambda n: n ** 2
r = f2(5)
print(r)
# sort()
l = [
{'name': '鹿晗', 'age': 30},
{'name': '蔡徐坤', 'age': 20},
{'name': '宋小宝', 'age': 40},
{'name': '贾玲', 'age': 35},
{'name': '林志玲', 'age': 50}
]
# 普通函数
def fn(d):
return d['age']
# l.sort(key=lambda d: d['age'])
l.sort(key=fn)
print(l)
print("***" * 50)
# 回调函数
# fn1:既是函数名称,也是指向该函数的一个变量
# 函数调用: 只要是指向该函数的变量,都可以调用该函数
def fn1():
print('hello')
# fn1()
fn2 = fn1
fn2()
# 回调
def fm(x, f):
n = f(x)
print(n)
def f1(m):
return m * m
fm(10, f1)
# fm(10, lambda m: m * m)
# 封装一个sort功能的函数
def my_sort(ll, key=None):
# 冒泡排序
for i in range(len(ll) - 1):
for j in range(len(ll) - 1 - i):
left = ll[j]
right = ll[j+1]
if key:
left = key(left)
right = key(right)
if left > right:
ll[j], ll[j + 1] = ll[j + 1], ll[j]
my_sort(l, key=lambda d: d['age'])
print(l)
# 匿名函数,多个参数
f7 = lambda a, b: a+b
print(f7(1, 3))
值传递和引用传递
值传递:传参的过程中传递的是值,一般指的是不可变的数据类型,number,tuple,string
引用传递:传参的过程中传递的是引用,一般指的是可变的数据类型,list,dict, set
# 基本类型赋值: 不关联
a = 10
b = a
a = 20
print(a, b) # 20 10
# 引用类型赋值: 关联
l1 = [1, 2, 3]
l2 = l1
l1[0] = 99
print(l1, l2) # [99, 2, 3] [99, 2, 3]
# 函数中
age = 10
person = {'name': '小明', 'age': 43}
def change_age(age1, person1):
age1 += 1
person1['age'] += 1
# def change_age(): # age =11
# global age
# age += 1
# person['age'] += 1
change_age(age, person)
print(age, person) # 10 {'name': '小明', 'age': 44}
引用传递本质上传递的是内存地址
练习题
"""【以下功能都使用函数封装】
提示: 涉及到要返回的题目,请使用return"""
''' 基础题 '''
# 1.封装函数,计算从1到某个数以内所有奇数的和并返回
def he1(n):
sum1 = 0
for i in range(1, n + 1, 2):
sum1 += i
return sum1
print(he1(100))
# 2.封装函数,判断某个数是否是偶数,返回结果(True或False)
def is_ou(n):
return n % 2 == 0
result = is_ou(58)
print(result)
# 3.封装函数,交换某两个变量的值, 并返回结果
def change(a, b):
return b, a
result = change(3, 5)
print(result)
# 4,封装函数,将某个字符串中的大写字母转换为小写,小写字母转换为大写,将新的字符串返回【参数设置为默认参数】
# swapcase()
def swap(str1='asD'):
return str1.swapcase()
result = swap()
print(result)
''' 进阶题 '''
# 1.封装函数,比较某两个数的大小,返回较大的一个
def bj(a, b):
return a if a > b else b
result = bj(4, 7)
print(result)
# 2.封装函数,判断某个数是否是素数,返回结果(True或False)
def is_prime(n):
if n == 1:
return False
for i in range(2, n):
if n % i == 0:
return False
return True
result = is_prime(56)
print(result)
# 3.封装函数,计算2-100之间素数的个数,返回结果
def fs():
count = 0
for n in range(2, 101):
if is_prime(n):
count += 1
return count
print(fs())
''' 进阶题 '''
# 1,封装函数,实现如下要求
# 例如:输入2,5,则求2+22+222+2222+22222的和
def f2(a=2, n=5):
s = 0
t = 0
for i in range(n):
t = t * 10 + a
s += t
return s
print(f2())