栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

小甲鱼python学习笔记之函数

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

小甲鱼python学习笔记之函数

函数可以重复的实现某个功能,减少代码冗余;可以将不同功能的代码进行封装,简化代码结构,提高代码可读性。

函数

函数的打包和调用函数的返回值函数的实参和形参函数的参数

位置参数关键字参数默认参数

使用help查看函数文档 收集参数

参数的打包参数的解包 作用域

局部作用域全局作用域嵌套函数LEGB规则 闭包

定义用法闭包的两个特性

函数的打包和调用
>>> def myfunc():
	pass

>>> myfunc()
>>> def myfunc():
	for i in range(3):
		print("I LOVE")

		
>>> myfunc()
I LOVE
I LOVE
I LOVE
 def myfunc(name):
	for i in range(2):
		print("I Love {}".format(name))

		
>>> myfunc("Pyhton")
I Love Pyhton
I Love Pyhton
>>> 
>>> def myfunc(name,time):
	for i in range(time):
		print("I love {}".format(name))

		
>>> myfunc("Pyhotn",4)
I love Pyhotn
I love Pyhotn
I love Pyhotn
I love Pyhotn
函数的返回值
def div(x,y):
	return x/y

>>> div(4,2)
2.0
>>> def div(x,y):
	if y==0:
		return "被除数不能为零"
	else:
		return x/y

	
>>> div(2,0)
'被除数不能为零'
>>> div(6,3)
2.0

如果一个函数没有通过return来显示的返回内容,那么他也会自己在执行完函数体中的所有语句之后,返回一个None值

def myfunc():
	pass

>>> print(myfunc())
None
函数的实参和形参

定义函数时的参数为形参,调用函数时传入的值为实参

函数的参数

参数就是接口,只要按照函数的要求将指定的参数正确的传递进去,函数就可以返回正确的结果。Python有多种参数。

位置参数

根据形参定义的位置传递实参

def myfunc(s,vt,o):
	return "".join((o,vt,s))

>>> myfunc("我","爱","中国")
'中国爱我'
>>> myfunc("中国","爱","我")
'我爱中国'
关键字参数

根据参数的名字(形参名)传递参数进去,位置顺序可以忽略。

>>> def myfunc(s,vt,o):
	return "".join((o,vt,s))

>>> myfunc(o="我",vt="打了",s="小甲鱼")
'我打了小甲鱼'

== 位置参数必须在关键字参数之前,否则会报错==

>>> myfunc(o="我","清蒸","xiaojiayu")
SyntaxError: positional argument follows keyword argument
>>> myfunc("清蒸","鱼",o="我")
'我鱼清蒸'
默认参数

函数定义时给形参赋一个值,如果调用函数时没有给这个参数传递实参进去,就默认使用定义时赋的值。

>>> def myfunc(s,vt,o="yu"):
	return "".join((o,vt,s))

>>> myfunc("香蕉","吃")
'yu吃香蕉'
使用help查看函数文档

使用help()函数来查看函数文档时,经常会在函数的原型中看到一个斜杠(’ / ‘),斜杠左侧的参数必须传递位置参数,而不能使用关键字,星号(’ * ')表示左侧既可以是位置参数,也可以是关键字参数。

>>> help(abs)
Help on built-in function abs in module builtins:

abs(x, /)
    Return the absolute value of the argument.

>>> help(sum)
Help on built-in function sum in module builtins:

sum(iterable, /, start=0)
    Return the sum of a 'start' value (default: 0) plus an iterable of numbers
    
    When the iterable is empty, return the start value.
    This function is intended specifically for use with numeric values and may
    reject non-numeric types.

>>> abs(-1.5)
1.5
>>> abs(x=-1.5)
Traceback (most recent call last):
  File "", line 1, in 
    abs(x=-1.5)
TypeError: abs() takes no keyword arguments
>>> sum([1,2,3],start=4)
10
>>> def abc(a,/,b,c):
	print(a,b,c)

	
>>> abc(3,b=4,c=8)
3 4 8

自己也可以这样定义函数以及参数

def abc(a,*,b,c):
	print(a,b,c)

	
>>> abc(1,b=2,c=4)
1 2 4
>>> abc(a=1,b=2,c=4)
1 2 4
>>> print("我","爱","Python")
我 爱 Python
>>> def myfunc(*args):
	print("有{}个参数".format(len(args)))
	print("第2个参数是,{}".format(args[1]))

	
>>> myfunc("小甲鱼","不二入市")
有2个参数
第2个参数是,不二入市
>>> myfunc(1,2,3,4,5)
有5个参数
第2个参数是,2
收集参数 参数的打包
    打包为元组
    函数不知道用户需要传入多少个参数,比如print()函数可以支持参数可多可少的情况,拥有这种特性的形参称为收集参数。它的本质是元组,使用元组打包和解包的特性。
>>> def myfunc(*args):
	print(type(args))

	
>>> myfunc()

如果在收集参数之后还需要指定其他参数,那么在调用函数是,就应该使用关键字参数来指定后面的参数,否则Python就会把实参纳入到收集参数中:

>>> def myfunc(*args,a,b):
	print(args,a,b)

	
>>> myfunc(1,2,3,4,5)
Traceback (most recent call last):
  File "", line 1, in 
    myfunc(1,2,3,4,5)
TypeError: myfunc() missing 2 required keyword-only arguments: 'a' and 'b'
>>> myfunc(1,2,3,a=4,b=5)
(1, 2, 3) 4 5
    打包为字典
    除了上面的将实参打包为元组,还可以将实参打包为字典
def myfunc(**kwargs):
	print(kwargs)

	
>>> myfunc(a=1,b=2,c=3)
{'a': 1, 'b': 2, 'c': 3}
    还可以将其混合起来,既包含元组也包含字典,如字符串的format方法
>>> def myfunc(a,*b,**c):
	print(a,b,c)

	
>>> myfunc(1,(1,2,3),c="Pyhon")
1 ((1, 2, 3),) {'c': 'Pyhon'}
>>> myfunc(1,2,3,4,5,x=5,y=6)
1 (2, 3, 4, 5) {'x': 5, 'y': 6}
>>> help(str.format)
Help on method_descriptor:

format(...)
    S.format(*args, **kwargs) -> str
    
    Return a formatted version of S, using substitutions from args and kwargs.
    The substitutions are identified by braces ('{' and '}').
参数的解包

在形参上使用称为参数的打包,在实参上使用称为解包

args=(1,2,3,4)
>>> def myfunc(a,b,c,d):
	print(a,b,c,d)

	
>>> myfunc(args)
Traceback (most recent call last):
  File "", line 1, in 
    myfunc(args)
TypeError: myfunc() missing 3 required positional arguments: 'b', 'c', and 'd'
>>> myfunc(*args)     //解包为元组
1 2 3 4
>>> kwargs={'a':1,'b':2,'c':3,'d':4}
>>> myfunc(kwargs)
Traceback (most recent call last):
  File "", line 1, in 
    myfunc(kwargs)
TypeError: myfunc() missing 3 required positional arguments: 'b', 'c', and 'd'
>>> myfunc(**kwargs)  //解包为字典
1 2 3 4
作用域

作用域是指一个函数可以被访问的范围,由代码中被赋值的位置来决定的

局部作用域

若一个变量被赋值在函数的内部,作用域仅限于该函数中,称为局部变量

全局作用域

若在函数中存在一个跟全局一模一样的局部变量,该全局变量在函数内部可以访问但是不可以修改它的值。

>>> def myfunc():
	return 1,2,3

>>> myfunc()
(1, 2, 3)
>>> x,y,z=myfunc()
>>> x
1
>>> y
2
>>> z
3
>>> def myfunc():
	x=520
	print(x)

	
>>> myfunc()
520
>>> print(x)
1
>>> id(x)
1798563588400
>>> def myfunc():
	x=520
	print(id(x))

	
>>> myfunc()
1798603569936

若要在函数内部修改全局变量的值,需要使用global进行声明

>>> def myfunc():
	global x
	x = 520
	print (x)

	
>>> myfunc()
520
嵌套函数

调用内部函数只能通过外部函数来调用

>>> def A():
	x=520
	def funB():
		x = 880
		print("in funB,x={}".format(x))
	print("in funA,x=",x)

>>> A()
in funA,x= 520
>>> def A():
	x=520
	def funB():
		x = 880
		print("in funB,x={}".format(x))
	funB()
	print("in funA,x=",x)

	
>>> A()
in funB,x=880
in funA,x= 520	

在内部函数中修改外部函数的变量时需要使用nonlocal进行声明

>>> def A():
	x=520
	def funB():
		nonlocal x
		x = 880
		print("in funB,x={}".format(x))
	funB()
	print("in funA,x=",x)

	
>>> A()
in funB,x=880
in funA,x= 880
LEGB规则
英文名称作用域范围注释/说明
LLocal局部作用域————
EEnclosed嵌套函数的外层函数作用域在嵌套函数中,局部作用域会覆盖外层函数的作用域,需要使用nonlocal进行声明
GGlobal全局作用域当局部作用域与全局作用域发生冲突时,Python会使用局部作用域的变量,除非使用Global进行声明
BBuild In内置作用域避免使用Python的BIF内置函数作为变量名
闭包

在嵌套函数中,有两种方式可以调用内部函数:

通过外部函数来调用内部函数

>>> def A():
	x=520
	def funB():
		nonlocal x
		x = 880
		print("in funB,x={}".format(x))
	funB()   
	print("in funA,x=",x)

	
>>> A()     //通过外部函数来调用内部函数
in funB,x=880
in funA,x= 880

不通过外部函数来调用内部函数(函数指针)

>>> def funA():
	x=880
	def funB():
		print(x)
	return funB

>>> funA()
.funB at 0x000001A2C5232790>   //得到一个funB的引用
>>> funA()()
880
>>> f=funA()        //调用funA()将这个变量赋给一个函数
>>> f()
880

上面的代码出现了一个神奇的现象:外部函数中定义的变量在外部函数调用完之后就没有意义了(funA函数中定义的变量x在f=funA()语句执行完之后就没有意义了),但是还是可以通过调用内部函数打印它( x )的值。

对于嵌套函数来说,外层函数的作用域是会通过某种形式给保存下来的,尽管这个函数已经调用完了,但是外层作用域的变量会保存下来,不会像局部作用域一样调用完就消失了

定义

闭包 也称为工厂函数,根据上述现象利用嵌套函数来实现类似工厂的功能。

>>> def power(exp):
	def exp_of(base):
		return base ** exp
	return exp_of

>>> square = power(2)    //嵌套函数的外部作用域会被保存下来,在执行该语句时,square指向exp_of这个内部函数,这个函数就记住了外层函数作用域的参数exp=2
>>> cube = power(3)     //cube变量指向exp_of这个函数,这个内部函数记住了exp=3
>>> square(2)
4
>>> square(5)
25
>>> cube(2)
8
>>> cube(5)
125

外部函数power相当于一个工厂,由于参数不同,得到了两条不同的生产线

    square 返回参数的平方cube 返回参数的立方
用法

使用nonlocal语句可以让嵌套函数的内层函数修改外层函数的变量

>>> def outer():
	x = 0
	y = 0
	def inner(x1,y1):
		nonlocal x,y
		x += x1
		y += y1
		print(f"现在,x = {x}, y = {y}")
	return inner

>>> move = outer()
>>> move(1,2)
现在,x = 1, y = 2
>>> move(-2,2)
现在,x = -1, y = 4

利用内层函数能够记住外层函数作用域这一特性,且使用nonlocal语句,让内层函数修改外层函数作用域中的变量,实现了带记忆功能的函数。

闭包的两个特性

利用嵌套函数的外层作用域具有记忆功能的特性,让数据保存在外层函数的参数或者变量中将内层函数作为返回值返回,从外部函数间接调用内层函数

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/754071.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号