Fork me on GitHub

day-11

1. 可变长参数

1.1 可变长参数之形参

1.1.1 *形参名

def f1(*args):	# *args(默认的写法)用元组接收多余的位置实参
    print(args)
    
f1()	# 不传参数
f1(1)	# 传一个
f1(1, 2, 3, 4, 5)	#传多个

运行结果:

# 多余的变量值使用元组存储
()			
(1,)
(1, 2, 3, 4, 5)

Process finished with exit code 0

1.1.2 **形参

def f1(**kwargs):	# **kwargs(默认的写法)用字典接收多余的关键字实参,将字典的值赋给参数
    print(kwargs)


f1()
f1(x=1)
f1(x=1, y=2)

运行结果:

# 多余的变量值使用字典存储
{}	# 不传参数
{'x': 1}	# 传一个
{'x': 1, 'y': 2}	# 传多个

Process finished with exit code 0

1.2 可变长参数之实参(了解)

1.2.1 *实参

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) 	# * 把列表中的元素打散成位置实参依次传给位置形参

运行结果:

1 2 3 4 5 6 7

Process finished with exit code 0

1.2.1 **实参

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


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

运行结果:

1 2

Process finished with exit code 0

2. 函数对象

python中一切皆对象

对象的四大功能:

  1. 引用
  2. 用作容器元素
  3. 作为函数的实参
  4. 当作函数的返回值

函数的对象

函数的对象 == 函数名

def f1():	# 定义一个函数 f1(),函数对象是 f1
    print('from f1')

1. 函数对象的引用

func = f1	# func 引用函数对象 f1 ,则 func 也具有了函数的功能
print('f1:', f1)
print('func:', func)
func()

运行结果:

f1: <function f1 at 0x0000019477EB34C8>
func: <function f1 at 0x0000019477EB34C8>
# f1 和 func 指向的内存地址是相同的    
from f1	# 运行了函数 f1

Process finished with exit code 0

2. 当作容器类元素

lt = [f1, 1, 2, 3]	# 将函数对象当作容器类元素

print('lt[0]:', lt[0])	# 取出列表内的第一个元素
print('f1:', f1)	# 打印 f1 的内存地址

lt[0]()	# lt[0] 取出了函数对象,加上()直接调用函数

运行结果:

lt[0]: <function f1 at 0x0000025308EB34C8>
f1: <function f1 at 0x0000025308EB34C8>
# f1 和 lt[0] 指向的内存地址是相同的  
from f1	# 运行了 f1 函数

Process finished with exit code 0

3. 作为函数的实参

def f2(f2_f1):
    print('f2_f1', f2_f1)
    f2_f1()


print('f1', f1)
f2(f1)

运行结果:

f2_f1 <function f1 at 0x0000022D6C343798>
from f1
f1 <function f1 at 0x0000022D6C343798>

4. 当作函数的返回值

def f2(f2_f1):
    return f2_f1


res = f2(f1)
print('res', res)
print('f1', f1)

res()

运行结果:

res <function f1 at 0x000001F93C5E3798>
f1 <function f1 at 0x000001F93C5E3798>
from f1

Process finished with exit code 0

3. 函数的嵌套

函数里面再定义函数。

  • 函数的嵌套
# 定义函数,只检测语法,不会执行代码
def f1():
    print('from f1')

    def f2():
        print('from f2')
  • 函数的嵌套调用

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

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

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

运行结果:

from f1

Process finished with exit code 0

4. 名称空间和作用域

4.1 名称空间

内存中存储变量名与变量之间绑定关系的空间。

4.1.1 内置名称空间

存放 python 解释器自带的内置方法的名字,如: int float print def ……

4.1.1 局部名称空间

用于存放函数调用期间函数体产生的名字,即存放函数内部定义的变量名的空间。

如下面的: xf2

def f1():
    x = 10
    def f2():
        z = 20

4.1.1 全局名称空间

除了内置名称空间和局部名称空间外,其他所有的名称都存放再全局名称空间。

如下面的: x func lt

x = 1

def func():
    pass

lt = [1, 2]

4.1.1 加载顺序

内置名称空间>>>全局名称空间>>>局部名称空间

python解释器加载完内置名称空间后才能打开文件,打开文件后会产生全局名称空间,当文件内的某个函数被调用,再产生局部名称空间。

4.1.1 查找顺序

当前所在的空间查找>>>局部名称空间查找>>>全局名称空间查找>>>内置名称空间查找>>>报错

# 这里使用关键字当作变量名,是为了演示查找顺序,实际使用不要这样命名

# 1
len  =10

def f1():
    len = 20

    print('1:', len)	#先查找当前名称空间,即查找局部名称空间找到为:20

f1()

# 2
len  =10

def f1():
    print('2:', len)	#当前局部名称空间查找不到,查找全局名称空间找到为:10

f1()

# 3
def f1():
    print('3:', len)	#当前局部全局名称空间都查找不到,查找内置名称空间:找到内置函数 len

f1()

运行结果:

# 1
1:20
# 2
2:10
# 3
3:<built-in function len>

Process finished with exit code 0

4.2 作用域

4.2.1 全局作用域

全局作用域包括内置名称空间和全局名称空间。

全局作用域的变量 x 和局部作用域的变量 x 没有任何关系。

y = 10	# 定义一个变量 y

def f1():	# 定义一个函数 f1 ,作用是让 y = 2
    y = 2	


f1()	# 调用函数,是函数生效

print(y)	# 打印 y

运行结果:

10	# y = 10,局部作用域的变量 y 并没有被全局作用域的变量 y 影响

Process finished with exit code 0

4.2.2 局部作用域

局部作用域只包含局部名称空间。

局部作用域1的 x 和局部作用域2的 x 没有任何关系,即便他们处于同一个局部作用域下。

# 函数 f2 和 f3 同属于一个局部作用域下
def f1():
    def f2():
        def f3():	
            x = 1	
            print(x) # 打印 f3 局部作用域下的 x = 1

        x = 2	# 让 f2 局部作用域下的 x = 2
        f3()

    f2()

f1()    # 调用函数 f1

运行结果:

1	# 局部作用域 f3 下的变量 x 并没有被局部作用域 f2 下的 x 影响

Process finished with exit code 0

4.3 补充

4.3.1 globalnonlocal (尽量不要使用)

  • global

    global 以下的局部作用域的变量变成全局作用域的变量

    不使用global

    x = 10
    
    def f1():
        # global x  # 让global以下的局部的x变成全局的x
        x = 20
    
    
    f1()
    print(x)
    

    运行结果:

    10
    
    Process finished with exit code 0
    

    使用global 后:

    20
    
    Process finished with exit code 0
    
  • nonlocal

    nonlocal 让变量成为顶层函数的局部作用域的变量,注意不是成为全局作用域的变量(没有应用情景,生产中尽量不要嵌套函数)

    不使用nonlocal

    def f1():
        def f2():
            def f3():
                # nonlocal x  # nonlocal让x成为顶层函数的局部
                x = 1
    
            x = 2
            f3()
            print(x)
    
        f2()
        
    f1()
    

    运行结果:

    2
    
    Process finished with exit code 0
    

    使用nonlocal 后:

    def f1():
        def f2():
            def f3():
                nonlocal x  # nonlocal让x成为顶层函数的局部
                x = 1
    
            x = 2
            f3()
            print(x)
    
        f2()
        
    f1()
    

    运行结果:

    1
    
    Process finished with exit code 0
    

4.3.2 所有可变数据类型均可打破上述一切规则

lt = [0]
def f1():	# 局部作用域内接收了全局作用域定义的变量 lt ,并且改变了 全局作用域下的 lt 的内容,
    lt.append(1)	# 1.向列表添加值
    lt[0] = 1	    # 2. 更改列表第一个值


f1()
print(lt)

运行结果:

[0, 1]	# 1.
[1, 1]	# 2.
posted @ 2019-09-20 19:53  Yugaliii  阅读(107)  评论(0编辑  收藏  举报