前言
hi~可爱的人类,欢迎点进我的Python系列学习笔记~
这篇文章,我会初步介绍Python中相关函数的概念,以及其内置函数的相关应用,一起来学习吧~
--------------------------------------------------------------------------------------------------------------------------------
目录
一、函数相关定义以及参数
1.函数定义
Python中定义函数需要用到关键字def:
函数格式:
def funcname (paras):
[
'''
说明信息
'''
]
statements
return [expression]
def:
定义函数所需要的关键字。
''':
函数的说明信息,可以通过help(函数名)进行查看。
funcname:
函数名。
paras:
函数的参数,参数之间用,隔开
statements:
函数体。
expression:
返回值。
函数有如下几点需要注意的:
首先是说明信息:可有可不有:
def Print():
"""
单纯的打印字符串函数
"""
print("Helloworld")
return
Print()
help(Print)
使用help(函数名)就可以查看此函数的相关说明,也可以使用函数名._doc_的方式访问。其中return可以省略,无返回值会默认返回None,可以打印出来。
print(Print())
注意Python中变量保存的是对象的引用。(这也解释了之前的组合数据类型对象单纯的=还是同一空间的问题),Python中函数名也是一个变量,直接输出函数名的话就会输出函数变量在内存中的地址。
2.函数参数
我们知道,定义函数的时候,参数表的参数就被称为形式参数,也就是形参,而在调用函数的时候,参数表中提供的参数就是实参了。
参数传递:
首先,Python中函数的传递有两种形式:
1.位置参数:
根据参数表的顺序,实参按照先后顺序传递给形参。
比如如下代码:
def add(num1, num2):
return num1 + num2
print(add(1.2, 2))
按照顺序将参数值1.2给num1,2给num2。
2.赋值参数:
但是有的时候参数过多,每个参数用法不同的话,普通的位置参数进行传参的话就会出现不方便并且可读性下降等问题,所以此时就有赋值参数这一说法:
即在调用函数的时候,在括号中传参时标注号参数名,后面加上=
函数名(参数1= , 参数2=, ...) 此时参数先后顺序任意。
比如如下代码:
# 输入五门科目的成绩,为了方便传参,使用赋值参数
def get_score(pe, eng, math, phy, chem):
return pe * 0.5 + eng * 1 + math * 1.2 + phy * 1 + chem * 1
print(get_score(93, 98, 65, 78, 70)) # 位置参数进行传递
print(get_score(pe=93, math=65, eng=98, phy=78, chem=70)) # 赋值参数进行传递 此时位置随意
形参和实参:
当传入的参数为基本数据类型的时候(整型类型、浮点数类型、字符串类型...),此时是值传递的状态,即形参不改变外面的实参。
def Swap(f1, f2):
f1, f2 = f2, f1
a = 1
b = 2
print(a, b)
Swap(a, b)
print(a, b)
比如如上实现的一个交换函数,由于传递的只是值而不是外面实参的本身,所以内部形参进行交换并不会改变外部实参的变化。
但是当传入的参数是列表、元组、字典、集合等组合数据类型的时候,那么此时传入的就不是单纯的值传递了,而是引用进行传递。形象一点说就是形参也外面实参组合数据类型对象的一个别名,可以影响到外面的实参:
def test(a):
a.append(5)
arr = [1, 2, 3, 4]
print(arr)
test(arr)
print(arr)
默认参数:
类似于C++中的缺省参数,Python中也提供了默认参数这一说法,即在函数定义的时候,参数给上一定的默认值,如果调用未传此参数的值就会使用此默认值。
def test(a, b, c=1):
return a + b + c
print(test(1, 2))
和C++一致,默认参数只能从后往前给,半缺省只能是从后往前连续的默认参数,全缺省也就是全为默认参数:
def test1(a1, b1=1, c1=1): # 半缺省
return a1 + b1 + c1
def test2(a2=1, b2=1, c2=1): # 全缺省
return a2 + b2 + c2
print(test1(1))
print(test2())
可变参数:
在Python中,对于参数除了传统意义上的必须传递的参数(默认参数可以视为默认传递),还新增了一种可变参数。
对于可变参数有如下两种形式:
*args:
args为参数名字,前面一个*号(可不是C/C++中的指针哦~在Python中无此概念),表示在传统参数传递完后,剩余的参数(非关键字参数)用元组的形式进行保存。
**kwargs:
kwargs同样为参数名字,前面为两个**(可不是C/C++中的二级指针哦),表示如果传入的参数指定了名称,也就是关键字参数,那么此可变参数会用字典的形式保存这些被命名的参数。
用下面的一段代码理解可变参数的含义:
def test(name, student_ID, *args, **kwargs):
print("姓名:", name)
print("学号:", student_ID)
print(type(args))
for i in args:
print(i, end=",")
print(type(kwargs))
for j in kwargs.items(): # 取出全部的键值对
print(j, end=" ")
print("\n------------------------------")
test("张三", "21080") # 可以默认不传可变参数的值
test("张三", "21080", "2022", 18) # 剩余参数由*args可变参数存储在元组中
test("张三", "21080", "2022", 18, math=98, eg=100) # 存在关键字参数就存储在**kwargs可变参数--字典中
3.lambda函数
当我们需要能在一行就能将功能表示出来并且之后也很少去复用的时候,这个时候lambada函数就起作用了。
lambda函数是Python中的匿名函数(无名字,通过类似键=值进行复用)。
语法格式:
lambda 参数:函数体(函数表达式,不能包含分支和循环语句)
参数之间用,进行分隔,通常为位置参数。
lambda函数的应用场景是定义简单的,能在一行内表示的函数,返回的是一个函数类型。
lambda函数能够很方便的应用在函数式编程中:
比如如下计算圆柱的体积:
import math
area = lambda r: math.pi * r * r
volume = lambda r, h: math.pi * r * r * h
print("{:.2f}".format(area(2)))
print("{:.2f}".format(volume(2, 2)))
然后使用sorted(可迭代对象,key=函数类型,reverse=False)函数(默认升序),进行按照key值进行排序。利用lambda匿名函数进行按照绝对值进行排序:
lis = [-9, -5, -6, -1, 4, 5, 0, 3]
print(lis) # 原列表
print(sorted(lis)) # 默认升序
print(sorted(lis, reverse=True)) # 反转,逆序
print(sorted(lis, key=lambda x: abs(x))) # 按照绝对值大小进行升序
def test(x):
return abs(x)
print(sorted(lis, key=test, reverse=True)) # 绝对值逆序,不适用lambda函数
二、闭包
闭包(Closure)是一种重要的语法结构,Python支持这种结构。
闭包实际上就是一个嵌套函数(在函数内再次定义函数 -- 内部函数)引用了外层函数的变量,然后外部函数返回此嵌套函数名(即函数类型)。这个函数就可以被称为闭包函数。此时,被引用的变量就和闭包函数一同存在,即使离开外部函数的作用域也是如此。
Python中创建闭包函数的条件:
闭包函数必须要有嵌套函数。(原本的嵌套函数只能在此函数内部使用)
嵌套函数需要引用外部函数中的变量。
外部函数需要将嵌套函数名作为返回值返回。
用一个打招呼的程序来说明闭包函数:
def call_external(prefix): # prefix就是属于外部函数的变量
def call(name): # 定义嵌套函数
print(prefix, name) # 引用了外部函数的变量
return call # 外部函数返回嵌套函数 -- 此时此嵌套函数就是闭包函数
Call = call_external("Good morning")
Call("小王") # 此时Call就是闭包函数的引用了
Call("张三")
Call = call_external("Good afternoon")
Call("小王")
Call("张三")
注意此时的外部函数的变量prefix的生命周期就不是外部函数的了,而是和闭包函数一起。
三、变量的作用域
函数在传参过程中涉及到形参和实参不是同一个的类型。这就是由于变量的作用域不同所导致的。首先作用域和变量是否是基本数据类型还是组合数据类型有关。下面介绍的是基本数据类型,组合数据类型传参过程中传递的是引用--即还是它自己。
局部变量:
局部变量是定义在函数体内的变量,此时此局部变量的作用域以及声明周期就从定义它的此刻开始直到函数结束为止。(闭包函数引用的外部变量除外)同样,在不同的作用域局部变量之间或者和全局变量互不影响(即使重名):
但是注意如果在局部作用域内先使用与全局变量同名的变量就会出现问题。
全局变量:
和局部变量的定义相反,也就是定义在函数体外的变量就是全局变量。此时在各个函数内部只允许访问--只读(因为这里是Python,如果像C/C++里面那套的话会认为定义的是和全局变量同名的局部变量),如果想要修改全局变量,就需要提前在函数内部声明此变量为全局变量(使用关键字 global 全局变量名),这样才不会让解释器以为是局部变量。
用一下代码解释上述重点内容:
age = 19 # 全局变量
def test():
print(age) # 此时就出现问题,原本访问的是全局变量,但是此时下面定义的有局部,就会报错
age = 18 # 局部变量
test()
age = 18
print(age)
def test():
# 此时想修改全局变量
global age # 表示age为全局变量
age = 19
test()
print(age)
四、Python的内置函数
内置函数就是可以自动加载,之间使用的函数。Python提供了很多实现各种功能的内置函数,具体如下:
1.数学运算函数
函数 | 功能 | 例子 |
abs() | 返回给入基本数据类型的绝对值 | abs(-2) |
divmod() | 返回两个数的商和余数 | divmod(10, 3)(返回的是一个元组) |
max() | 返回可迭代对象的最大值或者所有参数的最大值,默认参数key可以指定规则选择 | max(-1, 2, 3) max('avda') |
min() | 返回可迭代对象的最小值或者所有参数的最小值,默认参数key可以指定规则选择 | min(-1 ,2, 4, 4) |
pow() | 求两个参数的幂运算值。第三个参数就是求前两个幂运算的取余运算 | pow(2, 3) pow(2, 3, 5) |
round() | 返回浮点数的四舍五入值即整型值 | round(1.23432) |
sum() | 对元素类型是数值的可迭代对象的每个元素求和,最多支持两个参数哦 | sum((1, 2, 3, 4)) sum((1, 2), -10) |
print(divmod(10, 3))
print(type(divmod(10, 3))) # 元组类型
print("-------------------------")
print(max(-1, 2, -9, 3)) # 默认按照实际大小进行筛选
print(max(-1, 2, -9, 3, key=abs)) # 指定规则进行筛选
print(min(-1, 2, -9, 3, key=lambda x: abs(x)))
print("-------------------------")
print(2**3) # 幂运算
print(pow(2, 3))
print(pow(2, 3, 5)) # 幂运算后进行取余
print("-------------------------")
print(round(1.5))
print(round(1.2))
print(round(1.53))
print(type(round(1.34234242)))
print("-------------------------")
print(sum((1, 2, 3), -10))
# print(sum(1, 2)) # 非可迭代对象是不行的哦~
2.字符串运算函数
相关函数已经整理放在这里啦,有兴趣的可以前去观看哦~
【Python3】Python中的字符串_柒海啦的博客-CSDN博客
3.转换函数
函数 | 功能 |
bool() | 返回布尔值 |
int() | 转换为整数 |
float() | 转换为浮点数 |
complex() | 转换为复数(一个字符串比如'1 + 2j',或者传入两个参数) |
str() | 返回一个对象的字符串表现形式 |
ord() | 返回'Unicode'对应的码值 |
chr() | 返回码值对应的Unicode字符 |
bin() | 整数转化为二进制字符串 |
oct() | 将整数转化为八进制字符串 |
hex() | 将整数转化为十六进制字符串 |
需要注意的是int()不传入参数时返回0,float()返回0.0,complex()返回0j
print(complex('1-2j'))
print(complex(1, -2))
4.序列操作函数
序列作为一个重要的数据结构,包括字符串、列表、元组等。以下函数主要针对于列表和元组这两种数据结构:
函数 | 功能 |
all(iteration) | 判断可迭代对象的每个元素是否都为True,返回True |
any(iteration) | 判断可迭代对象是否含有True,返回True |
range([start,]end[, sep]) | 产生一个序列,从0开始(详细可以查看Python程序结构中for) |
map(function, iter1[,iter2......]) | 用指定的方法去操作传入的每个可迭代对象的元组,生成新的可迭代对象(后面传入的可迭代对象个数由前面的映射函数决定) |
filter(function, iter) | 使用指定方法过滤可迭代对象的元素(指定的方法返回True就表示保留元素,返回False就过滤掉此元素) |
reduce(function, iter) | 使用指定方法累积可迭代对象的元素(function函数必须要有两个参数,两个参数首先是可迭代对象的0和1对应元素,然后以此返回结果作为下一次的第一个参数,然后以第三元素为第二个参数...直到元素遍历完) |
zip(iter1[,iter2...]) | 聚合传入的每个迭代器中相同位置的元素(聚合成元组),返回一个新的元素类型迭代器 |
sorted(iter, [reverse=False, key=函数类型]) | 排序,返回一个新的列表 |
reversed(lter) | 反转生成新的可迭代对象 |
# zip()聚合相同位置
print(list(zip([1, 2, 3], [4, 5]))) # 以最少元素的迭代器对象为组数
print(list(zip([1, 2, 3], [4, 5, 9]))) # 以最少元素的迭代器对象为组数
print(list(reversed([1, 2, 3])))