一、命名关键字参数
对于关键字参数,函数的调用者可以传入任意不受限制的关键字参数 。至于到底传入了哪些,就需要在函数内部通过kw
检查。
仍以person()
函数为例,我们希望检查是否有city
和job
参数:
def person(name, age, **kw): if ‘city‘ in kw: # 有city参数 pass if ‘job‘ in kw: # 有job参数 pass print(‘name:‘, name, ‘age:‘, age, ‘other:‘, kw)
但是调用者仍可以传入不受限制的关键字参数:
person(‘Jack‘, 24, city=‘Beijing‘, addr=‘Chaoyang‘, zipcode=123456)
如果要限制关键字参数的名字,就可以用命名关键字参数,例如,只接收city
和job
作为关键字参数。这种方式定义的函数如下:
def person(name, age, *, city, job): print(name, age, city, job)
和关键字参数**kw
不同,命名关键字参数需要一个特殊分隔符*
,*
后面的参数被视为命名关键字参数。
调用方式如下:
person(‘Jack‘, 24, city=‘Beijing‘, job=‘Engineer‘) Jack 24 Beijing Engineer
如果函数定义中已经有了一个可变参数,后面跟着的命名关键字参数就不再需要一个特殊分隔符*
了:
def person(name, age, *args, city, job): print(name, age, args, city, job)
命名关键字参数必须传入参数名,这和位置参数不同。如果没有传入参数名,调用将报错:
person(‘Jack‘, 24, ‘Beijing‘, ‘Engineer‘) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: person() takes 2 positional arguments but 4 were given
由于调用时缺少参数名city
和job
,Python解释器把这4个参数均视为位置参数,但person()
函数仅接受2个位置参数。
在*后面的参数都是命名关键字参数,传值的时候必须按照关键字参数进行传值,*args后面的参数也是命名关键字参数,命名关键字参数可以有缺省值(city是默认参数可以不传值),从而简化调用:
def person(name, age, *, city=‘Beijing‘, job): print(name, age, city, job)
由于命名关键字参数city
具有默认值,调用时,可不传入city
参数
使用命名关键字参数时,要特别注意,如果没有可变参数,就必须加一个*
作为特殊分隔符。如果缺少*
,Python解释器将无法识别位置参数和命名关键字参数:
def person(name, age, city, job): # 缺少 *,city和job被视为位置参数 pass
二、函数对象
函数是第一类对象: 指的是函数的内存地址可以像一个变量值一样去使用
def foo(): foo=函数的内地址
print(‘from foo‘)
1. 变量值可以被引用
x=1 #foo=函数的内地址 y=x f=foo print(f) f()
2. 变量值可以当作参数传给另外一个函数
def bar(x): print(x) x() x=11111 #foo=函数的内存地址 bar(x) bar(foo)
3. 变量值可以当作函数的返回值
def func(x): return x f=func(foo) print(f)
4. 变量值可以当作容器类型的元素
l=[foo,] print(l) l[0]() dic={‘1‘:foo} print(dic) dic[‘1‘]() def register(): print(‘注册....‘) def login(): print(‘登录....‘) def pay(): print(‘支付....‘) def transfer(): print(‘转账....‘) func_dic={ ‘1‘:register, ‘2‘:login, ‘3‘:pay, ‘4‘:transfer } func_dic[‘1‘]() while True: print(""" 0 退出 1 注册 2 登录 3 支付 4 转账 """) choice=input(‘请输入你的操作: ‘).strip() if choice == ‘0‘:break if choice not in func_dic: print(‘输错的指令不存在‘) continue func_dic[choice]()
三、函数的嵌套
函数的嵌套调用:在一个函数内部又调用其他函数
def max2(x,y): if x > y: return x else: return y def max4(a,b,c,d): res1=max2(a,b) res2=max2(res1,c) res3=max2(res2,d) return res3 print(max4(1,2,3,4))
函数的嵌套定义: 在函数内又定义了其他函数
def func(): def foo(): print(‘from foo‘) print(foo) foo() x=1 print(x) func()
四、 名称空间与作用域
4.1 名称空间相关
名称空间Namespaces:指的就是存放名字与值内存地址绑定关系的地方(内存空间)
4.2 名称空间分为三大类
内置名称空间: 存放的是python解释器自带的名字
产生:python解释器的启动则产生
销毁:python解释器关闭则销毁
全局名称空间: 在顶级定义的名字
x=1 if True: y=2 while True: z=3 def func(): pass
产生:执行python程序时产生
销毁:python程序执行完毕后则销毁
局部名称空间: 在函数内定义的名字
def foo(): m=100 foo()
产生: 在函数调用时临时产生
销毁: 在函数调用完毕后则销毁
三种名称空间的产生的先后顺序: 内置->全局->局部
查找名字的顺序:从当前位置往外一层一层查找
如果当前在局部名称空间: 局部->全局->内置
如果当前在全局名称空间: 全局->内置
4.3 作用域:指的是作用范围
全局作用域:包含内置与全局名称空间的名字
特点:全局存活,全局有效
局部作用域:包含局部名称空间的名字
特点:临时存活,局部有效
全局作用域:包含的是内置名称空间与全局名称空间的名字,
特点
在任何位置都能够访问的到
该范围内的名字会伴随程序整个生命周期
局部作用域:包含的是局部名称空间的名字
特点:
只能在函数内使用
调用函数时生效,调用结束失效
!!!作用域关系是在函数定义阶段就已经固定死了,与调用位置无关
示范一:
def f1(): print(xxx) xxx=111 def f2(): xxx=222 f1() f2()
示范二:
xxx=111 yyy=333 def f1(): xxx=222 print(xxx) #xxx=222 yyy=222 print(yyy) f1()
五、闭包函数
闭:封闭,指的是该函数是定义一个函数内部的函数
包:该内部函数包含对外层函数名字的引用
def outter(): x=1 def inner(): print(‘from inner‘,x) return inner f=outter() def foo(): # print(f) x=111111111111111111111111111111111111 f() foo()
为函数体传值的两种方式
方式一:直接以参数的形式传入
def foo(name): print(‘hello %s‘ %name) foo(‘egon‘) foo(‘egon‘) foo(‘egon‘)
方式二:闭包函数
def outter(name): # name=‘egon‘ def foo(): print(‘hello %s‘ %name) return foo f=outter(‘egon‘) # print(f) f() f() f() f1=outter(‘alex‘) f1() f1() f1()
pip3 install requests
import requests
问题
def get():
response=requests.get(url)
if response.status_code == 200:
print(response.text)
def get(url): response=requests.get(url) if response.status_code == 200: print(response.text) get(‘https://www.baidu.com‘) get(‘https://www.baidu.com‘) get(‘https://www.baidu.com‘)
解决方案一
def outter(url): # url=‘https://www.baidu.com‘ def get(): response=requests.get(url) if response.status_code == 200: print(response.text) return get baidu=outter(‘https://www.baidu.com‘) cnblogs=outter(‘https://www.cnblogs.com‘) baidu() baidu() baidu() baidu() baidu() baidu() baidu() baidu() baidu() baidu() baidu() baidu() cnblogs() cnblogs() cnblogs() cnblogs() cnblogs() cnblogs() cnblogs() cnblogs() cnblogs() cnblogs() cnblogs() cnblogs() cnblogs() cnblogs() cnblogs() cnblogs() cnblogs()
解决方案二
原文地址:https://www.cnblogs.com/596014054-yangdongsheng/p/9709090.html