函数的返回值
现在有一个需求,比较两个人的月薪,然后想获取月薪较大人的年薪。
如果需要在程序中拿到函数的处理结果做进一步的处理,则需要函数必须要有返回值。
需要注意的是:
- return是一个函数结束的标志,函数内可以有多个return,只要执行到return,函数就会执行。
- return的返回值可以返回任意数据类型
- return的返回值无个数限制,即可以使用逗号隔开返回多个值
- 0个:返回None
- 1个:返回值是该值本身
- 多个:返回值是元组
#返回单个值 def max_self(salary_x, salary_y): if salary_x > salary_y: return salary_x else: return salary_y max_salary = max_self(20000, 30000) print(max_salary*12) ##360000 #返回多个值 def fun(): name = 'nick' age = 19 hobby_list = ['read', 'run'] return name, age, hobby_list name, age, hobby_list = func()#解压缩 print(f"name,age,hobby_list: {name, age, hobby_list}") ##name,age,hobby_list:{'nick', 19, ['read', 'run']}
函数的调用
#函数调用的三种方式 def max_self(x, y): if x>y: return x else: return y # 1. max_self(1, 2) # 2. res = max_self(1, 2)*12 # 3. max_self(max_self(20000, 30000),40000)
函数的参数
#形参,本质是变量名 def func(x, y): print(x) print(y) ##位置形参 def func(x, y): print(x) print(y) ##默认形参 def fun(x, y=10): print(x) print(y) func(2) ''' 注意: 1.位置形参必须放在默认形参的左边 2.默认形参的值只在定义阶段赋值一次,也就是说默认参数的值在函数定义阶段就已经固定了 ''' #实参,本质是变量的值 func(1, 2) #位置实参,函数调用阶段,按照从左到右的顺序依次定义的实参。 func(1, 2) #关键值实参,调用函数时,按照key=value的形式指定的参数传值 func(y=2, x=1) ''' 注意: 1.可以混用位置实参和关键字实参,但是位置实参必须在关键字实参的左边 2.可以混用位置实参和关键字实参,但不能对同一个形参重复赋值 func(x, y=2) func(y=2, x) # SyntaxError:positional argument follows keyword argument func(x, x=1) # NameError: name 'x' is not defined ''' '''
可变长参数
#可变长参数之* ## 形参(会把溢出的位置实参全部接收,然后存成元组形式,然后把元组赋值给*后的参数) def sun_self(*args): res = 0 for num in args: res += args: return res res = sun_self(1, 2, 3, 4) print(res) ### 10 ## 实参(会把*后参数的值循环取出,打散成位置实参,遇到了就想到去打散) def func(x, y, z, *args): print(x, y, z, args) func(1, *(1, 2), 3, 4): ### 1 1 2 (3, 4) #可变长参数之** ## 形参(**会把溢出的关键字实参全部接收,存储成字典的形似,然后把字典赋值给*后的参数) def func(**kwargs): print(kwargs) func(a=5) ### {'a', 5} ## 实参(**会将**后的参数的值循环取出,打散成关键字实参,遇到了就想到去打散) def func(x, y, z, **kwargs): print(x, y, z, kwargs) func(1, 3, 4, **{'a': 1, 'b': 2}) ### 1 3 4 {'a': 1, 'b': 2}
函数对象
''' 函数是第一类对象,即函数可以被当作数据处理 ''' def func(): print('from func') print(func) ###<function func at 0x10af72f28> #函数对象的四大功能 ##1.引用 x = 'hello nick' y = x f = func print(f) ###<function func at 0x10af72f28> ##2.当做参数传给一个函数 len(x) def foo(m): m() foo(func) ### from func ##3.可以当做函数的返回值 def foo(x): return x res = foo(func) print(res) res() ###<function func at 0x10af72f28> ###from func ##4.可以当做容器类的元素 i = [x] function_list = [func] function_list[0]() ###from func
名称空间和作用域
""" 1.内置名称空间 存放Python解释器自带的名字,如int、float、len 在解释器启动时生效,在解释器关闭时失效 """ ''' 2.局部名称空间 用于存放函数调用期间函数体产生的名字,如f2 在文件执行时函数调用期间时生效,在函数执行结束后失效 ''' def f1(): def f2(): print('from f2') f2() f1() ''' 2.全局名称空间 除了内置和局部的名字之外,其余都存放在全局名称空间,如x, func, 1, z ''' x = 1 def func(): pass l = [1, 2] if 3 > 2: if 4 > 3: z = 3 #加载顺序 ##内置---》全局---》局部 #查找顺序 ##当前位置--->局部---》全局---》内置 x = 1 def func(): print(x) x = 10 func() #10 ##作用域 ###全局作用域 x = 1 def bar(): print(x) bar() #1 ###局部作用域 def f1(): def f2(): def f3(): print(x) x = 2 f3() f2() f1() #2 ''' 作用域注意点 x = 1 def f1(): #定义阶段 x = 1 print(x) def f2(): x = 2 f1() f2() #1 ''' #作用域的应用 def f1(): def inner(): print('from inner') return inner f = f1() #把局部定义的函数放在全局之中 def bar(): f() bar() # from inner ## global关键字 x = 1 def f1(): x = 2 def f2(): # global x # 修改全局 x = 3 f2() f1() print(x) # 1 x = 1 def f1(): x = 2 def f2(): global x x = 3 f2() f1() print(x)n # 3(global把x声明为全局变量之后,x指向3这个变量值,所以打印的是3) ##nonlocal x = 1 def f1(): x = 2 def f2(): x = 3 f2() print(x) f1() # 2 x = 1 def f1(): x = 2 def f2(): nolocal x #针对嵌套函数局部之间的修改 x = 3 f2() print(x) f1() # 3 ''' 注意点: 1.在局部想要修改全局的可变类型,不需要任何声明,可以直接修改。 2.在局部如果想要修改全局的不可变类型,需要借助global声明,声明为全局的变量,即可直接修改 ''' lis = [] def f1(): lis.append(1) print(f"调用函数前:{lis}") f1() print(f"调用函数后:{lis}") ''' 调用函数前:[] 调用函数后:[1] '''
闭包函数和装饰器
#闭包函数 def outter(x): x = 1 def inner(): print(x) return inner f = outter(1) f() f() f() # 1 # 1 # 1 #闭包函数的应用 import requests def outter(url): def get(): response = requests.get(url) print(response.text) return get baidu_spider = outter('https://www.baidu.com') baidu_spider() #直接爬取百度网页 #装饰器 # 直接在模板里面加入登录功能 def deco(func): def wrapper(*args, **kwargs): #登录功能 inp_username = input('请输入用户名:') inp_password = input("请输入密码:") if inp_username == 'nick' and inp_password == '123': print("登录成功") else: print("登录失败") res = func(*args, **kwargs) return res return wrapper @deco def shopping(): print("欢迎来到购物模块") shopping() ''' #装饰器模板 def deco(func): def wrapper(*args, **kwargs): res = func(*args, **kwargs) return res return wrapper '''
迭代器
#可迭代的对象:Python内置str、list、tuple、dict、set、file都是可迭代对象。 ''' 特点: 1.内置有__iter__方法的都叫可迭代的对象 ''' ''' 迭代器对象:执行可迭代对象的__iter__方法,拿到的返回值就是迭代器对象。 特点: 内置__next__方法,执行该方法会拿到迭代器对象中的一个值 内置有__iter__方法,执行该方法会拿到迭代器本身 文件本身就是迭代器对象。 缺点: 取值麻烦,只能一个一个取,并且只能往后取,值取了就没了 无法使用len()方法获取长度 ''' #for循环:称为迭代器循环,in后必须是可迭代对象 ''' 因为迭代器使用__iter__后还是迭代器本身,因此for循环不用考虑in后的对象是可迭代对象还是迭代器对象。 由于对可迭代对象使用__iter__方法后变成一个迭代器对象,这个迭代器对象只是占用了一小块内存空间,他只有使用__next__后才会吐出一个一个值。如lis = [1,2,3,4,5,...]相当于一个一个鸡蛋,而lis = [1,2,3,4,5,...].__iter__相当于一只老母鸡,如果你需要蛋,只需要__next__即可 '''