第七章 函数

7.1 函数的定义

  • 概念:功能(包裹一部分代码,实现某一功能,达成某一个目的)
  • 特点:可以反复调用,提高代码的复用性,提高开发效率,便于维护管理

7.1.1 函数基本格式

# 定义函数
def 函数名():
	code
#调用函数
函数名()

7.1.2 函数的命名

  • 命名规范:
    • 字母、数字、下划线,且字母不能为数字
    • 严格区分大小写,且不能使用关键字
    • 函数命名有意义,且不能使用中文
  • 驼峰命名法:
    • 大驼峰命名法:每个单词的首字母要大写:
      • mycar => Mycar
    • 小驼峰命名法:除了第一个单词首字符小写外,剩下的单词首字母大写
      • mycar => myCar
    • 命名法:可以将不同单词用_拼接在一起
      • mycar => my_car
      • symmetric_difference
      def ctf_99():
      for i in range(1, 10):
        	for j in range(1, i + 1):
            print("{:d}*{:d}={:2d}".format(i, j, i * j), end="")
       	 print()
      
      for i in range(5):
      ctf_99()
      

7.1.3 函数的参数

  • 参数:函数运算时需要的值
    • 形参:形式参数,在函数的定义处
      • 普通形参(位置形参)
      • 默认形参
      • 普通收集形参
      • 命名关键字形参
      • 关键字收集形参
    • 实参:实际参数,在函数的调用处
      • 普通实参
      • 关键字实参
  • 原则:形参和实参要一 一对应

7.1.3.1 普通形参(位置形参)

# 定义函数
# a,b普通形参,在函数定义处
def func(a,b):
	print(a)
	print(b)
	
# 调用函数
# 1,2普通实参,在函数的调用处
func(1,2) # 1,2

7.1.3.2 默认形参

a,b默认形参,在函数定义处
如果给予实参,那么使用实参
如果没有给予实参,那么使用参数身上的默认值
"""
def func(a=1,b=2):
	print(a)
	print(b)

func()       # 1,2
func(10,20)  # 10,20
func(10)     # 10,2

7.1.3.3 普通形参 + 默认形参

# 普通形参必须放到默认形参的前面不能调换位置
# 正确:
def func(a,b=2):
	print(a)
	print(b)
func(10)

# 错误:
def func(b=2,a):
	print(a)
	print(b)
func(10,20)

7.1.3.4 关键字实参

"""
1.如果都是关键字实参,可以任意调整实参的顺序
2.普通实参必须写在关键字实参的前面
"""
def func(a,b,c,d=1)
	print(a,b)
	print(c,d)

# 具体定制参数的值叫做关键字实参,在函数的调用处
func(a=1,b=2,c=7,d=6)
func(a=1,b=2,5,d=6)   # error报错

7.1.3.5 收集形参

7.1.3.5.1 普通收集形参
  • 专门用来收集那些多余的没人要的普通实参

  • 收集之后,会把多余实参打包成一个元组

# arg => arguments
def func(a,b,c,*args):
	print(a,b,c)  # 1 2 3
	print(args)   # (4,5,6)
func(1,2,3,4,5,6)

# 任意个数值的累加和
def sum(*args):
	total = 0
	for i in args:
		total += i
	print(i)
sum(1,10)
7.1.3.5.2 关键字收集形参
  • 专门用来收集那些多余的没人要的关键字实参
  • 收集之后,会把多余关键字实参打包成一个字典
# kwargs => keyword arguments
def func(a,b**kwargs):
	print(a,b)     # 1 2
	print(kwargs)  # {'c': 3, 'd': 4}
func(a=1,b=2,c=3,d=4)

# 拼接任意个数值变成字符串
"""
班长: 赵万里
班花: 马春赔
吃瓜群: 美羊羊,沸羊羊,灰太狼   
"""
def func (**kwargs):
	strvar1 = ""
	strvar2 = ""
	# 定位职位信息
	dic = {"monitor":"班长","classflower":"班花"}
	print(kwargs)
	for k,v in kwargs.items():
		if k in dic:
		    # 将2次循环的结果通过+=拼接在一起
		    strvar1 += dic[k] + ":" + v +"\n"
		    print(strvar1)
		else:
		  # 将3次循环的结果通过+=拼接在一起
		    strvar2 += v +","
	print(strvar1.strip())
	print("划水群众:",strvar2.strip(","))
	
func(monitor="赵万里",classflower="马春赔",water1="美羊羊",water2="沸羊羊",water3="灰太狼")

7.1.3.6 命名关键字参数

"""
# 命名关键字参数
(1) def func(a,b,*,c,d)跟在*号后面的c和d
(2) def func(*args,e,**kwargs)加在*args和**kwargs之间的参数都是命名关键字参数

命名关键字参数:在调用函数时,必须使用关键字实参的形式来进行调用
"""
# 定义方法一:
def func(a, b, *, c, d):
    print(a, b)  # 1 2
    print(c, d)  # 3 4
	
# 必须指定关键字实参,才能对命名关键字形参进行赋值
func(1, 2, c=3, d=4)


# 定义方法二:
def func(*args, e, **kwargs):
    print(args)    # (1, 2, 3, 4)
    print(e)       # 3
    print(kwargs)  # {'a': 1, 'b': 2}

func(1, 2, 3, 4, a=1, b=2, e=3)


"""
# 星号的使用

* 和 **如果在函数的定义处使用
    * 把多余的普通实参打包成元组
    ** 把多余的关键字实参打包成字典

* 和 **如果在函数的调用处使用
     * 把元组或者列表进行解包
     ** 把字典进行解包
"""

def func(a, b, *, c, d):
    print(a, b)
    print(c, d)

tup = (1, 2)
# 函数的调用处 *号用法
func(*tup, c=3, d=4)

# 函数的调用处**号用法
dic = {"c": 3, "d": 4}
# func = (1,2,**dic)

# 综合写法
# 函数的调用处
tup = (1, 2)
dic = {"c": 3, "d": 4}
func(*tup, **dic)

# 定义成如下形式,可以收集所有的实参
def func(*args, **kwargs):
    pass

"""
总结:当所有的形参都放在一起,顺序原则:
    普通形参 -> 默认形参 ->普通收集形参 -> 命名关键字形参 -> 关键字收集形参
"""

def f1(a, b, c=0, *args, **kw):
    print('a=', a, 'b=', b, 'c=', c, 'args=', args, 'kw=', kw)


def f2(a, b, c=0, *,d ,**kw):
    print("a=", a, "b=", b, "c=", c,"d=",d , "kw=", kw)


# 以上俩个函数 打印结果
# (一)
f1(1, 2)                     # a= 1 b= 2 c= 0 args= () kw= {}
f1(1, 2, c=3)                # a= 1 b= 2 c= 3 args= () kw= {}
f1(1, 2, 3)                  # a= 1 b= 2 c= 3 args= () kw= {}
f1(1, 2, 3, "a", "b", x=99)  # a= 1 b= 2 c= 3 args= ('a', 'b') kw= {'x': 99}
f2(1, 2, d=99, ext=None)     # a= 1 b= 2 c= 0 d=99 kw= {'ext': None}

# (二)
args = (1, 2, 3, 4)
kw = {"d": 1, "b1": 3}
f1(*args, **kw)              # a= 1 b= 2 c= 3 args= (4,) kw= {'d': 1, 'b1': 3}

# (三)
args = (1, 2, 3)
kw = {"d": 88, "x": "#"}
f2(*args, **kw)

7.1.4 return 返回值

  1. 概念: return 把函数内部的数据返回到函数的外面,返回到函数的调用处

  2. 作用:

    (1) return 六大标准数据类型,除此之外还可以返回函数,或者是对象

    (2) return 在执行时,意味着终止函数,后面的代码不执行

    (3) 如果不定义return返回值,默认返回None

    # (1) return 六大标准数据类型
    def func():
    	# return 111
    	# return 6.89
    	# return "你好"
    	# return [1,2,3]
    	# return {"a":1,"b":2}
    	return 1,2,3 #返回元组
    
    res = func()
    print(res)
    
    # (2)终止函数,后面的代码不执行
    def func():
    	for i in range(5):
    		if i == 3:
    			return 4
    		print(i)
    res = func()
    print(res)
    
    # (3)如果不定义return返回值,默认返回None
    def func():
    	pass
    res = func()
    print(res) #None
    
    # (4)注意:打印的数据和返回值的数据不是等价的,返回的数据是可以自定义的
    res = print(1234)
    print(res)
    
    def func():
    	print(1234)
    res = func()
    print(res) #None
    
    # (5)练习:模拟器+-*/计算器
    """
    功能:完成计算
    参数: 2个数和运算符
    返回值: 计算后的结果
    """
    def calc(num1,num2,sign):
    	if sign == "+":
    	   return num1 + num2
    	elif sign == "-":
    		return num1 - num2
    	elif sign == "*":
    		return num1 * num2
    	elif sign == "/":
    		if num2 == 0:
    			return "除数不能为零"
    		return num1 / num2
    res = calc(3,5,"+") 
    res = calc(3,5,"-") 
    res = calc(3,5,"*") 
    res = calc(1,0,"/") 
    print(res)
    

7.2 函数小高级

  • python中的函数可以像变量一样,动态创建,销毁,
  • 可以当做参数传递,
  • 可以作为值返回,叫第一类对象,其他语言功能有限

7.2.1 函数动态创建与销毁

def func():
    print("我是func函数")

# (1)动态创建 
a = 1
print(a)
a = func
a()

# (2) 动态销毁
del a
# a()
# func()

7.2.2 函数当作参数传递

def func2():
    return "我是func2函数"

def func1(f):
    return f() #"我是func2函数"
res = func1(func2)
print(res)

7.2.3 函数当作值返回

def func3():
    print("我是func3函数")
       
def func4(f):
    return f

res = func4(func3)
print(res)
res()

7.2.4 函数名当作容器类型数据的元素

def func1():
	print(111)

def func2():
	print(222)
	
lst = [func1,func2]
for i in lst:
    i()

    
# __doc__或者help查看文档(双下划线)
def big_chang_cishen(something):
    """
    功能:教你怎么吃大肠
    参数:吃的内容
    返回值:是否满意 
    """
    print("把这个肠子洗洗")
    print("直接找肠子头,放嘴里,吸一下")
    print("擦擦嘴,满意的放下肠子头")
    return "吃完了,真好吃"

big_chang_cishen("生肠子")
# 方法一
res = big_chang_cishen.__doc__
print(res)
# 方法二
help(big_chang_cishen)

7.2.5 匿名函数:lambda表达式

  1. 作用: 用一句话来表达只有返回值的函数,简洁与高效

  2. 语法:lambda 参数: 返回值

    # (1)无参的lambda表达式
    def func():
    	return "文哥是个帅哥"
    
    # 改造
    func = lambda:"alex"
    print(func())   
    
    
    # (2)  有参的lambda表达式
    def func(n):
    	return id(n)
    
    # 改造
    func = lambda n: id(n)
    print(func(100))
    
    
    # (3) 带有判断条件的lambda表达式
    def func(n):
    	if n % 2 == 0:
    		return "偶数"
    	else:
    		return "奇数"
    
    # 三元运算符
    """
    语法:真值 if 条件表达式else 假值
    如果条件表达式成立为Ture,返回if前面的真值,反之,返回else后面的假值
    """
    n = 13
    res = "偶数"if n%2 == 0 else "奇数"
    print(res)
    
    
    # 小练习 比较两者之间的最大值进行返回
    def func(x,y):
    	if x > y:
    		return x
    	else:
    		return y
    print(func(1,2))
    
    # 改造 
    func = lambda x,y: x if x > y else y
    print(func(40,30))
    

7.3 函数中高级

7.3.1 函数的嵌套

  1. 形式: 互相嵌套的两个函数 包裹在外层叫做函数,内层的就是内函数

  2. LEGB原则(就近找变量原则):

    找寻变量的调用顺序采用LEGB原则(即就近原则)

    B - Builtin(python);python内置模块的命名空间(内建作用域)

    G - Global(module);函数外部所在的命名空间(全局作用域)

    E - Enclosing function locals;外部嵌套函数的作用域(嵌套作用域)

    L - Local(function):当前函数内的作用域(局部作用域) 依据就近原则,从下往上 从里向外 依次寻找

    def outer():
    	def inner():
    		print("我是inner函数")
    
    	inner()
    
    # (1)内部函数可以直接在函数外部调用吗? 不行
    inner()
    
    # (2)调用外部函数后,内部函数可以在函数外部调用吗? 不行
    outer()
    inner()
    
    # (3)内部函数可以在函数内部调用吗? 可以
    outer()
    
    # (4)内部函数在函数内部调用时,是否有先后顺序? 有的
    # 先定义在调用
    # 在其他语言中有预加载的机制,提前把函数驻留在内存中,然后再去编译脚本内容
    # python没有预加载函数的机制,只能先定义在调用
    
    # 外函数是outer 中间函数是inner 最里层是smaller,调用smaller函数
    def outer():
    	def inner():
    		def smaller():
    			print("我是smalller函数")
    
    		smaller()
    
    	inner()
    
    
    outer()
    
    
    def outer():
    	def inner():
    		def smaller():
    			print(id)
    
    		smaller()
    
    	inner()
    
    outer()
    

7.3.2 闭包函数

  1. 概念: 互相嵌套的两个函数,内函数使用了外函数的局部变量 ,并且外函数把内函数返回出来的过程,叫做闭包 里面的函数叫做闭包函数

  2. 判断是不是闭包: 内函数使用了外函数的局部变量 ,外函数返回内函数

    # 1.基本语法
    def xiaoming_family():
    	father = "马云"
    
    	def hobby():
    		print("我对钱没有一丝丝的兴趣,我不看重钱这是我爸爸{}说的".format(father))
    
    	return hobby
    
    
    func = xiaoming_family()
    func()
    tup = func.__closure__
    print(tup[0].cell_contents)
    print(tup)
    
    
    # 2.闭包的复杂形式
    def xiaohong_family():
    	gege = "王思聪"
    	didi = "高振宇"
    	money = 1000
    
    	def gege_hobby():
    		nonlocal money
    		money -= 500
    		print("我交朋友不在乎他有钱,钱还剩下{}".format(money))
    
    	def didi_hobby():
    		nonlocal money
    		money -= 400
    		print("家里有鞋柜,一双大概20~30万,钱物还剩下{}".format(money))
    
    	def big_master():
    		return [gege_hobby, didi_hobby]
    
    	return big_master
    
    
    func = xiaohong_family()
    print(func)
    lst = func()
    print(lst)
    
    # 获取哥哥函数
    gege = lst[0]
    gege()
    # 获取弟弟函数
    didi = lst[1]
    didi()
    
    # 3.使用__closure__,cell_contents判定闭包
    """如果返回的元组中有数据说明是闭包,谁的生命周期被延长就打印谁"""
    tup = func.__closure__
    print(tup)
    
    
    # 先获取第一个单元格 cell_contents获取对象中的内容
    func1 = tup[0].cell_contents
    func1()
    
    # 再获取第二个单元格 cell_contents获取对象中的内容
    func2 = tup[1].cell_contents
    func2()
    
    def func():
    		print(1)
    
    func()
    
    print(133)
    
    var =  id(123)
    
    # #### 闭包特点
    """
    特点:在闭包函数中,内函数使用了外函数的局部变量
    该变量会与内函数发生绑定,延长该变量的生命周期
    持续到脚本执行结束
    """
    
    def outer(val):
    	def inner(num):
    		return val + num
    	return inner
    func = outer(10)
    res = func(15)
    print(res)
    
    
    
    # ### 闭包的意义
    num = 0
    def click_num():
       global num 
       num += 1 
       print(num)
    
    click_num()
    click_num()
    click_num()
    num = 100
    click_num()
    click_num()
    
    # 改造,用闭包来实现
    def outer():
    	x = 0
    	def click_num():
    		nonlocal x
    		x += 1
    		print(x)
    	return
    func = outer()
    print(func)
    

7.4 作用域

  1. 概念:

    (1) 局部变量: 在函数内部定义的变量就是局部变量

    (2) 全局变量: 在函数外部定义的变量或者在函数内部使用global关键字声明是全部变量

  2. 作用域: 局部变量的作用范围仅仅在函数的内部 全局变量的作用范围横跨整个文件

  3. 生命周期: 该变量的作用时长

    内置命名空间 -> 全局命名空间 -> 局部命名空间(调用函数时,该局部变量会被创建,函数执行结束时,该局部变量会被立刻释放掉) 内置属性 > 全局属性 > 局部属性(从长到短)

    # 1.局部变量
    def func():
    	# 定义一个局部变量
    	a = 1
    	# 获取当前的局部变量
    	print(a)
    	# 修改一个局部变量
    	a = 2
    
    func()
    # print(a) error报错
    
    
    # 2.全局变量
    # 定义一个全局变量
    b = 10
    # 获取当前的全局变量
    print(b)
    b = 20
    # 修改一个全局变量
    print(b)
    
    def func():
    	print(b)
    
    func()
    

7.4.1 global的使用

  • 如果当前不存在全局变量,可以在函数内部通过global关键字来定义全局变量

  • 如果当前存在全局变量,可以在函数内部通过global关键字来修改全局变量

  • 用来修改全局变量

    # 1.函数内部定义全局变量
    def func():
    	global c
    	c = 30
    
    func()
    print(c)
    
    
    # 2.函数内部修改全局变量
    d = 50
    def func():
    	global d
    	d = 51
    
    func()
    print(d)
    

7.4.2 nonlocal的使用

  • 遵循LEGB原则
    • 他会找当前空间上一层的变量进行修改
    • 如果上一层空间没有,继续向上找寻找
    • 如果最后找不到,直接报错
  • 用来修改局部变量
    # (1)他会找当前空间上一层的变量进行修改
    def outer():
    	a = 10
    	def inner():
    		nonlocal a
    		a = 20
    		print(a)
    	inner()
    	print(a)
    outer()
    
    
    # (2) 如果上一层空间没有,继续向上寻找
    def outer():
    	a = 20
    	def inner():
    		def smaller():
    			nonlocal a
    			a = 30
    			print(a)
    		smaller
    		print(a)
    	inner()
    	print(a)
    outer()
    
    
    # (3)如果最后找不到,直接报错
    a = 20
    def outer():
    	def inner():
    		def smaller():
    			nonlocal a
    			a = 30
    			print(a)
    		smaller
    		print(a)
    	inner()
    	print(a)
    outer()
    
    
    # (4) 不通过nonlocal是否可以修改局部变量呢?
    def outer():
    	lst = [1,2,3]
    	def inner():
    		lst[-1] = 3000
    	inner()
    	print(lst)
    outer()
    

7.4.3 locals globals 其它使用

# ### locals globals使用(了解)

# locals 获取当前作用域所有的变量

# 1.全局空间
"""
locals 在函数外,获取的是打印之前所有的全局变量
locals 在函数内,获取的是调用之前所有的局部变量
"""
def func():
    a1 = 1
    b2  = 2
    
a = 1
b = 2
res = locals()
c = 3
print(res)
d = 4

# 2. 局部空间
a = 1
b = 2
def func():
    a1 = 1
    b2  = 2
    res = locals()
    c3 = 3
    print(res)
    d4 = 4
    
c = 3
func()
d = 4


# globals 
"""
globals在函数外,获取的是打印之前所有的全局变量
locals在函数内,获取的是调用之前所有的局部变量
"""
# 1.全局空间
"""
def func():
    a1 = 1
    b2 = 2

a = 1
b = 2
res = globals()
c = 3
print(res)

d = 4
"""

# 2.局部空间
"""
a = 1
b = 2
def func():
    a1 = 1
    b2 = 2
    res = globals()
    c3 = 3
    print(res)
    d4 = 4

c = 3
func() globals()
d = 4

"""

# ### globals 返回的是内置系统的全局字典
"""
res = globals()
print(dict)

dic['wangwen'] = "18岁"
print(wangwen)
"""

# 批量创建全局变量
def func():
    dic = globals()
    for i in range(1,5):
        # 批量在dic当中添加键值对,以创建全局变量
        dic ["a%d"%(i)] = i
        
        """
        dic["a1"] = 1
        dic["a2"] = 2
        dic["a3"] = 3
        dic["a4"] = 4
        """
func()
print(a1,a2,a3,a4)
posted @   柠檬の夏天  阅读(20)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示