day 11

可变长参数

可变长形参 *

*形参名

def f1(*args): # 调用函数时,有多少个位置实参,就接受多少个参数
    print(args)         
    
func(1,2,3,4) # (1,2,3,4)    

*args约定俗成的,用元组接收多余的位置实参

可变长实参 *

*实参

def f1(x,y,z,*args):
    print(x,y,z,*args)
   
func(1,*(1,2),3,4) # 1 1 2 (3,4)

可变长形参 **

def func(**kwargw):
    print(kwargw)
    
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}

**dic把字典打散成关键字实参然后传个函数f1

函数对象

函数时第一类对象,即函数可以被当做数据处理。

def func():
    print('from func')
  
print(func)  # <function func at 0x10af72f28>

函数对象的四大功能

引用

x = 'hello nick'
y = x

f = func
print(f)  # <function func at 0x10af72f28>

容器元素

lt = [x]

func_list = [func]
func_list[0]()  # from func

作为函数的实参

def f1(death):
    print(death)
   
f1(d)  

作为函数的返回值

def f1(s):
    return s

s2 = f1(s)

字典/列表/元组/集合/布尔值,所有对象都可以做以上四件事情

函数嵌套

定义

函数内部定义的函数,无法在函数外部使用内部定义的函数。

def f1():
    def f2():
        print('from f2')
    f2()
   
f2()	# NameError: name 'f2' is not defined
def f1():
    def f2():
        print('from f2')
    f2()
   
f1()	# from f2

函数嵌套的调用

def max2(x,y):
    if x > y:
        return x
    else:
        return y
   

def max_4(a,b,c,d):
    res1 = max_2(a,b)
    res2 = max_2(res1,c)
    res3 = max_2(res2,d)
    return res3

print(max(1,2,3,4))		# 4
    

名称空间和作用域

名称空间

内置名称空间

存放Python解释器自带的名字,如int、float、len

在解释器启动时生效,在解释器关闭时失效

全局名称空间

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

在文件执行时生效,在文件执行结束失效

x = 1


def func():
    pass


1 = [1,2]

if 3 > 2:
    if 4 > 3:
        z = 3

局部名称空间

用于存放函数调用期间函数体产生的。

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

def f1():
    def f2():
        print('from f2')
    f2()
   
f1()

加载顺序

由于.py文件是由Python解释器打开的,因此一定是在Python解释器中的内置名称空间加载结束后,文件才开始打开,这个时候才会产生全局名称空间,但文件内有某一个函数被调用的时候,才会开始产生局部名称空间,因此名称的加载顺序为:内置--》全局--》局部

查找顺序

由于名称空间是用来存放变量名与值之间的绑定关系的,所以但凡要查找名字,一定是从三者之一找到,查找顺序为:

从当前的所在位置开始查找,如果当前所在的位置为局部名称,则查找顺序为:局部--》全局--》内置

作用域

全局作用域

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

# 全局作用域
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
    

global关键字

修改全局作用域中的变量

x = 1

def f1():
    x = 2
    def f2():
        global	# 修改全局 
        x = 3
    f2()
   

f1()
print(x)			#	 1

nonlocal关键字

修改局部作用域中的变量

x = 1

def f1():
    x = 2
    
    def f2():
        nonlocal
        x = 3
        
    f2()
    print(x)
   

f1()				#    1

注意点

1.在局部想要修改全局的可变类型,不需要任何声明,可以直接修改。

2.在局部如果想要修改全局的不可变类型,需要借助global声明,声明为全局的变量,即可直接修改。

lis = []


def f1():
    lis.append(1)
    
   
print(f'调用函数前:{lis}')
f1()
print(f'调用函数后:{lis}')

调用函数前:[]

调用函数后:[1]

原文地址:https://www.cnblogs.com/colacheng0930/p/11559125.html