函数参数, 名称空间与作用域

可变长参数

*形参名

def f1(*args): #将多余的位置实参转化为元组形式接收

**形参名

def f1(**kwargs): #将多于的关键字实参转化为字典形式接收

以下仅作了解

*实参

*将容器类元素打散成位置实参依次传值给位置形参

如果是字典类型则只将关键字打散并传值

**实参

**只能将字典打散成关键字实参然后按对应形参名传值,字典中的key值必须与形参名一致

*args,**kwargs接收所有参数

默认形参必须在位置形参后面

t = ['a','b','c','d']
s = {'a','b','c','d'}
y = 'abcd'
r = ('a','b','c','d')
dic = {'a': 1, 'b': 2,'c':3,'d':4}
def f(*args,**kwargs):
    print(args,kwargs)
f(*y,**dic)

函数对象

python中一切皆对象

函数对象

函数对象 == 函数名 #函数名()就是在调用,没有其他意思

def f():
    print('from f')

1.引用

f1 = f
print('f:',f)
print('f1':f1)
f1()

2.当做容器类元素

lt = [1,2,f1,4]
print(lt[2])
lt[2]()

3.当做函数参数

def f2(x):
    print('当做函数f2的参数')
# f2(f)
print(f2(f))

def f3(x):
    print('当做函数f3的参数')
# f3(f())
print(f3(f()))

4.当做函数返回值

def f2():
    print('当做函数f2的返回值')
    return f
f2()
print(f2())
def f3():
    print('当做函数f3的返回值')
    return f()
f3()
print(f3())

函数嵌套

引入:循环嵌套,打印九九乘法表

for i in range(1,10):
    for j in range(1,i+1):
        print(f'{j}×{i}={j*i}',end=' ')
    print()

函数嵌套:函数里面有函数

定义函数,只检测语法,不执行代码

def f1():
	print('来自函数f1')
	def f2:
		print('来自函数f2')
res = f1()
print(res)
f2()	#报错
#函数内部定义的函数,外部不能使用

名称空间和作用域

变量名/函数名-->名称-->名称空间:专门存储名称

内置名称空间

作用:存放python解释器自带的名字,如int/float/len

生命周期:在python解释器启动时生效,在python解释器关闭时失效

全局名称空间

作用:除了内部和局部的名字之外,其余都存放在全局名称空间

生命周期:在文件执行是生效,在文件执行结束后失效

局部名称空间

作用:存放函数调用期间函数体产生的名字

生命周期:文件执行时函数调用期间生效,在函数执行结束后失效

名称空间的执行(生成)顺序

1.内置名称空间:python解释器启动的时候就有内置名称空间

2.全局名称空间:执行文件代码的时候才会有全局名称空间

3.局部名称空间:函数调用的时候才会有局部名称空间

名称空间的搜索顺序

先从当前所在位置寻找,找不到再按照局部-->全局-->内置的顺序寻找,并且不会逆方向寻找,找不到就报错

x = 10
def f():
    x = 10
    print(x)
print(x)
f()

名称空间的作用域

全局作用域中的x与局部作用于中的x无任何关系

全局作用域

全局有效,全局存活,包含内置名称空间和全局名称空间

局部作用域

局部有效,临时存储,只作用于局部名称空间

局部作用域2中的x和局部作用于3中的x也没有任何关系,即使它们都属于局部作用域1下

def f1():
    def f2():
        x=2
        def f3():
            x=1
            print(x)
        f3()
    f2()
f1()

注意点

作用域关系在函数定义阶段就固定死了,与函数调用无关

x = 10
def f1():
    x = 20
    print(x)
def f2():
    x = 30
    f1()
    print('f2打印的x:',x)
f2()

关键字修改作用域

global关键字

global先声明一个局部变量,在global声明以下的语句中所有的该局部变量全局变量

x = 10
def f():
    global x
    x = 20
print(x)
f()
print(x)

nonlocal关键字

nonlocal先声明一个局部变量,在nonlocal声明以下的语句中所有的该局部变量成为上层函数的局部变量,而不是成为全局变量

x = 40
def f1():
    x=30
    def f2():
        x=20
        def f3():
            nonlocal x
            x=10
            print('f3函数打印的x:',x)
        print('f3调用前f2函数打印的x:',x)
        f3()
        print('f3调用后f2函数打印的x:', x)
    print('f2调用前f1函数打印的x:',x)
    f2()
    print('f2调用后f1函数打印的x:', x)
f1()
print('不是函数打印的x:',x)

注意点

1.在局部想要修改全局的可变类型数据,不需要关键字声明,可以直接修改

2.在局部想要修改全局的不可变类型数据,需要用global关键字声明为全局变量再修改

lt = [1,2,3,4]
def f1():
    lt[3] = 371308
f1()
print(lt)
x = 10
def f2():
    global x
    x = 371308
f2()
print(x)

补充题目

def f1(i, lt=[]):
    lt.append(i)
    print(lt)
for i in range(10):
    f1(i)

def f1(i, lt):
    lt.append(i)
    print(lt)
for i in range(10):
    f1(i, [])
原文地址:https://www.cnblogs.com/-406454833/p/11567467.html