Python学习之旅-10 函数进阶
一、函数参数--动态传参
1、动态接收位置参数
在参数位置编写 * 表示接收任意内容
动态接收参数的时候要注意:动态参数必须在位置参数后面
这时程序运行会报错。因为前面传递进去的所有位置参数都被 *food接收了。a和b永远接收不到参数
2、动态接收关键字参数
在python中可以动态的接收参数,但是 * 这种情况只能接收位置参数无法接收关键字参数。
在python中使用 ** 来接收动态关键字参数
最终顺序:
位置参数 > *args > 默认值参数 > **kwargs
这四种参数可以任意的进行使用。
如果想接收所有的参数:
def func(*args, **kwargs):
print(args, kwargs)
func("麻花","驴打滚", wtf="胡辣汤")
动态参数的另一种传参方式:
def func(*args):
print(args)
lst = [1, 4, 7]
func(lst[0], lst[1], lst[2])
func(*lst) # 可以使用 * 把一个列表按顺序打散
s = "臣妾做不到"
func(*s) # 字符串也可以打散(可迭代对象)
在形参的位置上的* 表示把接收到的参数组合成一个元组
如果是一个字典,那么也可以打散,需要两个**
def fun(**kwargs):
print(kwargs)
dic = {'a':1, 'b':2}
fun(**dic)
3、函数的注释
二、命名空间
在python解释器开始执行之后,就会在内存中开辟一个空间,每当遇到一个变量的时候,就把变量名和值之间的
关系记录下来,但是当遇到函数定义的时候,解释器只是把函数名读入内存,表示这个函数存在了,至于函数内部的
变量和逻辑,解释器是不关心的。也就是说一开始的时候函数只是加载进来,仅此而已,只有当函数被调用和访问的时候
解释器才会根据函数内部声明的变量来进行开辟变量的内部空间。随着函数执行完毕,这些函数内部变量占用的空间也会
随着函数执行完毕而被清空。
def fun():
a = 10
print(a)
fun()
print(a) # a不存在了已经
我们给存放名字和值得关系的空间起一个名字叫:命名空间。我们的变量在存储的时候就是存储在这片空间中的。
命名空间分类:
1、全局命名空间--> 我们直接在py文件中,函数外声明的变量都属于全局命名空间
2、局部命名空间--> 在函数中声明的变量会放在局部命名空间
3、内置命名空间--> 存放python解释器为我们提供的名字,list, tuple ,str ,int 这些都是内置命名空间
加载顺序:
1、内置命名空间
2、全局命名空间
3、局部命名空间(函数被执行)
取值顺序:
1、局部命名空间
2、全局命名空间
3、内置命名空间
作用域:作用域就是作用范围,按照生效范围来看分为 全局作用域和局部作用域
全局作用域:包含内置命名空间和全局命名空间。在整个文件的任何位置都可以使用(遵循从上到下逐行执行)
局部作用域:在函数内部可以使用
作用域命名空间:
1、全局作用域: 全局命名空间 + 内置命名空间
2、局部作用域: 局部命名空间
我们可以通过globals()函数来查看全局作用域中的内容,也可以通过locals()来查看局部作用域中的变量
和函数信息
三、函数的嵌套
1、只要遇见了()就是函数的调用,如果没有()就不是函数的调用
2、函数的执行顺序
四、关键字global 和 nonlocal
global 表示,不再使用局部作用域中的内容了。而改用全局作用域中的变量
nonlocal 表示在局部作用域中,调用父级命名空间中的变量
五.函数的嵌套定义
#内部函数可以使用外部函数的变量
1.nonlocal
关于nonlocal只能用于局部变量招商层中离当前函数最近一层的局部变量
声明了nonlocal的内部函数的变量修改会影响到 离当前函数最近一层的局部变量
对全局无效,对局部也只是对最近的一层有影响
六.内存地址
函数名是一个变量,但它是一个特殊的变量,与括号配合可以执行函数的变量
1 func() #函数名就是内存地址 2 def func(): 3 print(123) 4 5 func2 = func #函数名可以赋值 6 func2() 7 l = [func,func2] #函数名可以作为容器类型的元素 8 def func(): 9 print(123) 10 11 def wahaha(f): 12 f() 13 return f 14 15 qqxing = wahaha(func) #函数名可以作为函数的参数 16 qqxing()
七.闭包
嵌套函数,内部函数调用外部函数的变量
1 def outer(): 2 a = 1 3 def inner(): 4 print(a) 5 print(inner.__closure__) #用到了closure然后返回的是cell,就说明它用到了闭包 6 return inner() 7 inn = outer() 8 inn()#在函数的外部去使用内部的一个形式
eg:
1 from urllib.request import urlopen 2 ret = urlopen('http://www.xiaohua100.cn/index.html').read 3 print(ret) 4 def get_url(): 5 url = 'http://www.xiaohua100.cn/index.html' 6 def get(): 7 ret = urlopen(url).read 8 print(ret) 9 return get 10 get_func = get_url() 11 get_url()