• 名称空间与作用域


    一、函数对象

      函数是第一类对象

      1、函数名是可以被引用

    1 def func():
    2     print('from func')
    3 a = func
    4 a()

      2、函数名可以当做参数传递

    1 def index(x, y, func):
    2     print(x, y)
    3     func()
    4 def foo():
    5     print('from foo')
    6 index(1, 2, foo)

      3、函数名可以当做返回值使用

    1 def index():
    2     print('from index')
    3 def func(a):
    4     return a
    5 b = func(index)
    6 b()

      4、函数名可以被当做容器类型的元素

    1 def func():
    2     print('from func')
    3 a = [1, '2', func]
    4 f = a[2]
    5 f()
     1 # 简单购物车
     2 def register():
     3     print('register')
     4 def login():
     5     print('login')
     6 def shopping():
     7     print('shopping')
     8 def pay():
     9     print('pay')
    10 def logout():
    11     print('logout')
    12 func_dict = {
    13     '1': register,
    14     '2': login,
    15     '3': shopping,
    16     '4': pay,
    17     '5': logout
    18 }
    19 def main():
    20     while True:
    21         print('''
    22         1、注册
    23         2、登录
    24         3、购物
    25         4、付款
    26         5、退出
    27         ''')
    28         choice = input(">>>>").strip()
    29         if choice == '5':
    30             func_dict[choice]()
    31             break
    32         elif choice not in func_dict.keys():
    33             continue
    34         else:
    35             func_dict[choice]()
    36 main()

    二、名称空间

      名称空间即存放名字与对象映射/绑定关系的地方。例如x=3,python会申请内存空间存放3,然后将名字x与3的绑定关系存放于名称空间中,执行时候会存在三种名称空间

      名称空间分类:

        ⑴、内置名称空间:伴随着python解释器的启动而产生,关闭而回收,是第一个被加载的名称空间,用来存放一些内置名称,比如内建函数名len,print

        ⑵、全局名称空间:伴随着pytho文件的开始执行而产生,执行完毕而回收,是第二个被加载的名称空间,文件执行过程中产生的名字都会存放于该名称空间中

        ⑶、局部名称空间:伴随着函数的调用而尝试,函数结束调用而回收,函数的形参、函数的定义的名字都会被存在于该名称空间中

      名称空间顺序:

          加载顺序:内置名称空间 > 全局名称空间 > 局部名称空间

          查找顺序:局部名称空间 > 全局名称空间 > 内置名称空间

        函数内部使用的名字,在定义阶段就已经规定死了,与你的调用位置无关

     1 x = 1
     2 def dex():
     3     print(x)
     4 def func():
     5     x = 2
     6     dex()
     7 func()
     8 # 输出:1
     9 
    10 x = 1
    11 def index(arg = x):
    12     print('x =', x, 'arg =', arg)
    13 x = 2
    14 index()
    15 # 输出:x = 2 arg = 1

    三、作用域

      1、全局作用域与局部作用域

        全局作用域:位于全局名称空间、内置名称空间中的名字属于全局范围。该范围内的名字全局存活、全局有效(在任意位置都可以使用)

        局部作用域:位于局部名称空间的名字属于局部范围。该范围内的名字临时存活(即在函数调用时临时生成,函数调用结束后就释放)、局部有效(只能在函数内使用)

      2、作用域与名字查找的优先级

        ⑴、在局部作用域查找名字时,起始位置是局部作用域,所以先查找局部名称空间,没有找到,再去全局作用域查找:先查找全局名称空间,没有找到再查找内置名称空间,最后没找到抛出异常

        ⑵、在全局作用域查找名字时,起始位置时全局作用域,所以先查找全局名称空间,没有找到再查找内置名称空间,最后没找到抛出异常

        ⑶、python支持函数的嵌套定义,在内嵌的函数查找名字时,会优先查找自己局部作用域的名字,然后由内而外一层层查找外部嵌套函数定义的作用域,都没有找到,则查找全局作用域

    x = 1
    def func():
        x = 2
        def index():
            x = 3
            print('内层:',x)
        index()
        print('外层:',x)
    func()
    # 结果为
    内层:3
    外层:2

        在函数内,无论嵌套多少层,都可以查看到全局作用域的名字,若要在函数内修改全局名称空间的名字值,需要用到global关键字

    1 x = 1
    2 def func():
    3     global x
    4     x = 2
    5 func()
    6 print(x)
    7 # 输出结果:2

        对于嵌套多层的函数,使用nonlocal关键字可以将名字声明为来自外部嵌套函数定义的作用域(非全局)

     1 def f1():
     2     x = 1
     3     def f2():
     4         x = 2
     5         def f3():
     6             x = 3
     7             def f4():
     8                 nonlocal x
     9                 x = 4
    10                 print('f4:', x)
    11             f4()
    12             print('f3:', x)
    13         f3()
    14         print('f2:', x)
    15     f2()
    16     print('f1:', x)
    17 f1()
    18 # 输出结果:
    19 f4:4
    20 f3:4
    21 f2:2
    22 f1:1

        ps:只有可变类型可以在局部修改外部变量的值

          不可变类型的局部变量的修改无法影响上层,上上层

  • 相关阅读:
    bzoj 2257 (JSOI 2009) 瓶子与燃料
    bzoj 2257 (JSOI 2009) 瓶子与燃料
    splay 模板 洛谷3369
    费用流 模板 洛谷3381
    bzoj 1024 [SCOI2009]生日快乐——模拟
    bzoj 3231 [Sdoi2008]递归数列——矩阵乘法
    hdu 5823 color II——子集dp(独立集)
    bzoj 1093 [ZJOI2007]最大半连通子图——缩点+拓扑
    洛谷 3959 宝藏——枚举+状压dp
    bzoj 1034 [ZJOI2008]泡泡堂BNB——贪心
  • 原文地址:https://www.cnblogs.com/hexianshen/p/11836436.html
Copyright © 2020-2023  润新知