python基础--函数进阶、名称空间和作用域

可变长参数

两种可变长形参

*形参名

def f1(*args):   # 调用函数时,有多少个位置实参,就接收多少个参数,组成元组
    print(args)
 
f1()   # 打印结果:()   # a是空元组
f1(1)  # 打印结果:(1, )  #注意有逗号
f1(1, 2)  # 打印结果:(1,2)
f1(1, 2, 3, 3, 4, 5, 5, 6, 7, 7, 7, 7, 7, 7, 7, )

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

**形参名

def f1(**kwargs):   # 调用函数时,有多少个关键字实参,就接收多少组参数,组成字典
	print(kwargs)

f1(x=1)  # 打印结果:{}   # 空字典

**kwargs,用字典接收多余的关键字实参

两种可变长实参

以下仅作了解

*实参

def f1(a, b, c, e, d, f, g):
	print(a, b, c, e, d, f, g)

lt = [1, 2, 3, 4, 5, 6, 7]
f1(lt[0],lt[1],lt[2],lt[3],lt[4],lt[5],lt[6])  # 一一传值
f1(*lt)  # *lt把列表中的元素打散成位置实参依次传给位置形参

**实参

def f1(a, b):
    print(a, b)

dic = {'a': 1, 'b': 2}  # a=1,b=2
f1(**dic)  # **dic把字典打散成关键字实参然后传给函数f1

函数对象

python中一切皆对象,函数也可以当作对象,有以下四大功能:

  1. 引用(拷贝)

  2. 当作容器类元素

  3. 当作函数的实参

  4. 当作函数的返回值

1、引用

def s():  # 定义函数s
	a = 10
	print(a)

x = s  # 引用函数s
x()  # x引用了函数s后也继承了函数的特性

2、当作容器类元素

def s():  # 定义函数s
	a = 10
	return a

lt = [1,s]  # 把函数s当作列表元素
print(lt[1])  # 打印结果为函数s的地址:<function s at 0x000001DBE30F1E18>
print(lt[1]())  # 打印结果为:10

3、作为函数的实参

def s():  # 定义函数s
	a = 10
	return a

def f1(b):  # 定义函数f1,b为形参
    c = b() + 5
    print(c)

f1(s)  # 把函数s当作实参传值给形参b

# 打印结果为:15

4、作为函数的返回值

def s():
    print('from s')

def f(a):
    """代码"""
    return s  # 函数s作为返回值,用于执行完函数f的功能后就返回函数s以供调用

res = f(2)
print(res)
res()

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

函数对象 == 函数名 # 函数名不带()

函数名() # 函数名带括号 就是在调用函数

函数嵌套

for循环的嵌套

打印九九乘法表

for i in range(1,10):
    for j in range(i):
        print(f'{j+1}*{i}={(j+1)*i}'',end='\t')  # \t是制表符,强制对齐
    print()   # 用于换行,每个i值的j循环完后就换行

打印结果为:

1*1=1	
1*2=2	2*2=4	
1*3=3	2*3=6	3*3=9	
1*4=4	2*4=8	3*4=12	4*4=16	
1*5=5	2*5=10	3*5=15	4*5=20	5*5=25	
1*6=6	2*6=12	3*6=18	4*6=24	5*6=30	6*6=36	
1*7=7	2*7=14	3*7=21	4*7=28	5*7=35	6*7=42	7*7=49	
1*8=8	2*8=16	3*8=24	4*8=32	5*8=40	6*8=48	7*8=56	8*8=64	
1*9=9	2*9=18	3*9=27	4*9=36	5*9=45	6*9=54	7*9=63	8*9=72	9*9=81

函数嵌套:函数里边定义函数

函数在调用之前只检测语法,不执行代码

函数内部定义的函数,外部不能调用

函数嵌套调用实例:

def max2(x,y):  # 定义第一个函数,
    if x > y:
        return x
    else:
        return y

def max4(a,b,c,d):  # 定义第二个函数
    res1 = max2(a,b)  # 调用第一个函数
    res2 = max2(c,d)  # 调用第一个函数
    res3 = max2(res1,res2)  # 调用第一个函数
    return res3

print(max4(1,2,3,4))   

这就是函数的调用,函数max4 里边嵌套调用了 max2 这个函数

名称空间和作用域

名称空间:专门用于存储名称的空间

名称空间主要分为以下三类:

1、内置名称空间:存储了内置方法的名称

数据类型自带内置方法;python解释器自带内置方法(print/len/list/str/dict)

2、全局名称空间:除了内置和局部都叫全局

3、局部名称空间:函数内部定义的都叫局部

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

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

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

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

搜索顺序:

先从当前所在位置寻找,找不到再按照这种顺序,不会逆着方向寻找 局部 --》 全局 --》 内置 --》 报错

作用域

全局作用域: 内置名称空间+全局名称空间 --》 全局作用域

局部作用域

1. 全局作用域的 x 和局部作用域的 x 没有半毛钱的关系

局部作用域:局部名称空间 --》 局部名称空间

2. 局部作用域1的x和局部作用域2的x也没有任何关系,即使局部作用域1和局部作用域2再同一个局部作用域下

global和nonlocal:仅作了解,尽量不要使用

global:打破了上述的第1点规则

global x # 让global以下的局部的x变成全局的x

nonlocal:打破了上述的第2点规则

nonlocal x # nonlocal让x成为顶层函数的局部,不是让他成为全局 # 压根没有应用情景,尽量不要嵌套函数

可变数据类型不受作用域的限制

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

posted @ 2019-09-20 20:48  AllenCH  阅读(209)  评论(0编辑  收藏  举报