[python基础] Part_3 函数的使用

作为面向对象语言, 函数是python中必须要掌握的一门知识

定义函数的目的就是为了方便使用, 同时也增加了代码的可读性

函数定义def

def test(x):		#定义函数
	print('test %s time'% x)
	
test(2)				#使用函数,传入参数
#运行结果:
test 2 time

函数的参数

必选参数

调用函数时必需的参数,如果在调用时没有给必选参数赋值就会报错

def fn(x):		#此时的x为必选函数
	return x*x

fn()
# 运行结果:
TypeError: fn() missing 1 required positional argument: 'x'

默认参数

定义函数时指定初始值的参数,必须要在必选参数之后,即使在调用函数时没有传参,也可以运行

def fn(a=3):		#此时的a为默认函数,初始值为3
	return a*a

fn()
# Result:
9

不定长参数

位置参数

接收任意数目的参数,组成一个tuple

def fn(*args):		#此时的args为位置函数
	return args
关键字参数

接收任意数目的键值对,组成一个dict

def fn(**kwargs):		#此时的kwargs为关键字函数
	return kwargs

这里的args 和kwargs代表普通的tuple和dict变量

内置函数

查看对象信息

id()查看内存地址
>>> a=2
>>> id(a)
140732454724464
type()查看对象的类型
>>> type('string')
<class 'str'>
isinstance()是否为指定类型
>>> isinstance('str',str)
True

常见函数

len() 求长度
s='abcd'
print(len(s))
#运行结果:
4
min() 求最小值
li=[1,2,3,4,5]
print(min(li))
#运行结果:
1
max() 求最大值
li=[1,2,3,4,5]
print(max(li))
#运行结果:
5
reversed() 反向

将序列反过来,镜像

li=[6,3,2,5,4]
a=reversed(li)
print(list(a))
#运行结果:
[4, 5, 2, 3, 6]
sum() 求和
li=[6,3,2,5,4]
print(sum(li))
#运行结果:
20

常见的高阶函数

关键字作用
sorted对列表进行排序,返回一个新的排序后的列表
enumerate返回一个可以枚举的对象
eval(‘1+1’)执行字符串中的表达式来求值并返回计算结果
exec执行字符串中的语句
filter过滤器
map(iterable,function)对参数iterable中的每个元素都应用function函数,并将结果作为列表返回
zip将对象逐一的配对
sorted() 排序

可以对序列类型进行正序或反序,sorted中的reverse默认值是False

li=[6,3,2,5,4]
print(sorted(li))		#正序
#运行结果:
[2, 3, 4, 5, 6]
print(sorted(li,reverse=True))		#反序
#运行结果:
[6, 5, 4, 3, 2]

和 li.sort() 的区别,

li=[5,8,4,3,9]
li.sort()
print(li)
#运行结果:		#彻底改变了原表的排序
[3, 4, 5, 8, 9]

li=[5,8,4,3,9]
print(sorted(li),li)	#只打印排序后的表,不改变原表排序
#运行结果:
[3, 4, 5, 8, 9] [5, 8, 4, 3, 9]

sorted本身是一个高阶函数,他可以传入一个函数,这个函数会对要排序的所有的对象依次进行运算,原算出来的结果作为排序的依据

students = ['bob','nacry','jack','op','kim','lasuadn']
print(sorted(students,key=len))	#传入len函数根据函数的长度排序
#运行结果:
['op', 'bob', 'kim', 'jack', 'nacry', 'lasuadn']
enumerate() 枚举

传入列表,提取元素索引,将索引和值组成一个字典

li=['a','b','c']
a=enumerate(li)
print(list(a))
#运行结果:
[(0, 'a'), (1, 'b'), (2, 'c')]
执行字符串的内容
eval()

执行字符串中的表达式

print(eval('3+2'))
#运行结果:
5
evec()

将字符串中的内容作为代码执行

print(exec('print(123)'))
#运行结果:
123
None
filter() 过滤器

只显示函数中返回True的情况,过滤掉False,返回值为可迭代对象

def fn(x):
	if x<3:  
		return True 
	else:
		return False

li = [1,2,3,4,5]
a=filter(fn,li)
print(list(a))
#运行结果:
[1,2]
map() 映射

将序列内的值作为参数传入函数中,并返回执行结果(可迭代对象)

def fn(x):
	return x*x*x

li = [1,2,3]
a=map(fn,li)
print(list(a))
#运行结果:
[1,2]
zip() 配对

将两个序列进行一一配对,输出一个有键值对的可迭代对象,多余的元素会被省略

li1=['a','b','c']
li2=[1,2,3,4]
li3=zip(li1,li2)
print(list(li3))
#运行结果:
[('a', 1), ('b', 2), ('c', 3)]

匿名函数lambda

匿名函数就是没有函数名的函数

lambda只适用于比较简单的表达式,如果单独使用lambda需要将表达式赋值到一个对象上,调用该对象

a=lambda x:x*x
print(a(3))
#运行结果:
9

lambda最适合用在filter、map这类函数上,匿名函数的合理利用能够让代码更加简洁

li=[1,2,3,4,5,6]
a=filter(lambda x:x<4,li)		#使用在filter
print(list(a))
#运行结果:
[1,2,3]
li=[1,2,3,4]
a=map(lambda x:x*2,li)			#使用在map
print(list(a))
#运行结果:
[2,4,6,8]

函数的作用域

函数的作用域具有以下四条原则:

1. 外部不能访问函数内部变量:
def fun1():
	x = 1
	return x
print(x)
#运行结果:
NameError: name 'x' is not defined
2. 函数内部能够访问函数外部变量:
x = 123
def  fun2():
	return x + 1
print(fun2())
#运行结果:
124
3. 函数里面不能修改函数外部变量:
x = 123
def  fun3():
	x = x + 1
	return x
print(fun3())
#运行结果:
UnboundLocalError: local variable 'x' referenced before assignment
4. 函数里面和函数外部变量名可以相同:

此处可以看出,函数内部的局部变量x的内存地址与外部的全局变量x不同

x = 123
print(x, id(x))
def  fun4():
	x = 456
	print(x, id(x))
	x += 1
	return x
print(fun4())
# 运行结果:
123 140726557930128
456 1889385718864
457

global(全局变量)

函数内部如果需要改变全局变量,就需要使用global修饰变量

x = 123
def   fun1():
	global x	#声明x的作用域为全局变量
	x += 1		#声明之后可以更改变量x的值
	return x
print(fun1())
# 运行结果:
124

nonlocal(局部变量)

在函数嵌套函数的情况下,同样也有函数作用域的问题,但是python3中提供了方便,只需要使用nonlocal就可以在里层函数内部修改外部函数变量

def  fun2():
	x = 123
	def fun3():
		nonlocal x		#声明x的作用域为局部变量
		x += 1			#声明之后可以更改局部变量x的值
		return  x
	return fun3()		#这里用的是一个闭包
print(fun2())
# 运行结果:
124

全局变量与局部变量的关系,请参考:

[外链图片转存失败(img-IeBt5dyN-1564408713891)(C:\Users\zh99294875\AppData\Roaming\Typora\typora-user-images\1547908778872.png)]

高级特性

闭包

要理解闭包首先要知道什么是 嵌套函数

def fun1():    #嵌套函数
	print('fun1()在被调用')    
	def fun2(): 				#在函数内部定义的函数称为嵌套函数
        print('fun2()在被调用')
    fun2()		
fun1()
# 运行结果:
fun1()在被调用
fun2()在被调用

下面来看一下闭包,闭包是函数里面嵌套函数,外层函数返回里层函数,这种情况称之为闭包

def fx(x):    
     x += 1    
     def fy(y):        
          return x*y    
     return fy
print(fx(5))		#这里的fx(5)的返回值是嵌套函数fy,由于fy没有传参因此返回结果是内存地址
# 运行结果:
<function fx.<locals>.fy at 0x0000022B59CC5268>

需要返回实际结果,就要使用以下方法:

print(fx(5)(5))
# 运行结果:
30

闭包是概念,不是某种函数类型,和递归的概念类似,就是种特殊的函数调用
闭包可以得到外层函数的局部变量,是函数内部和函数外部沟通的桥梁

递归

下面通过阶乘来演示一下递归的概念,递归中可以函数自身调用自身,但是使用时类似于条件循环一样,要有递归的终止条件

def jiecheng(x):
    if x==1:			#终止条件,当x为1时停止调用自身,返回1
        return 1
    return jiecheng(x-1)*x
print(jiecheng(5))
# 运行结果:
120

回调

自身是一个函数,只是被传入到另一个函数当中,供其调用。回调函数不一定会被调用,是否调用由被传入函数的内部逻辑决定

def a(fn):
    fn()
def b():
    print('b被调用了')
a(b)			#b被传入函数a后,变成b(),也就是fn()==>b()
# 运行结果:
b被调用了
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值