当前位置 博文首页 > python变量作用域与列表入门详解

    python变量作用域与列表入门详解

    作者:ruochen 时间:2021-07-14 18:49

    变量作用域

    变量由作用范围限制

    分类:按照作用域分类

    • 全局(global):在函数外部定义
    • 局部(local):在函数内部定义

    变量的作用范围

    • 全局变量:在整个全局范围都有效
    • 全局变量在局部可以使用(即函数内部可以访问函数外部定义的变量)
    • 局部变量在局部范围可以使用
    • 局部变量在全局范围无法使用

    LEGB原则

    • L(Local)局部作用域
    • E(Enclosing function local)外部嵌套函数作用域
    • G(Global module)函数定义所在模块作用域
    • B(Buildin):python内置模块的作用域
    # 认为a1是全局的
    a1 = 100
    
    def fun():
     print(a1)
     print("I am in fun")
     # a2的作用范围是fun
     a2 = 99
     print(a2)
     
    print(a1)
    fun()
    # print(a2)
    

    100
    100
    I am in fun
    99

    提升局部变量为全局变量

    使用global

    案例如下

    def fun():
     global b1 
     b1 = 100
     print(b1)
     print("I am in fun")
     b2 = 99
     print(b2)
    
    fun()
    print(b1)
    

    100
    I am in fun
    99
    100

    global,local函数

    可以通过globals和locals显示出局部变量和全局变量

    参考一下案例

    # globals 和 locals
    # globals 和 locals 叫做内建函数
    a = 1
    b = 2
    
    def fun(c,d):
     e = 111
     print("Locals={0}".format(locals()))
     print("Globals={0}".format(globals()))
      
    fun(100, 200)
    

    Locals={'c': 100, 'd': 200, 'e': 111}
    Globals={'__name__': '__main__', '__doc__': 'Automatically created module for IPython interactive environment', '__package__': None, '__loader__': None, '__spec__': None, '__builtin__': <module 'builtins' (built-in)>, '__builtins__': <module 'builtins' (built-in)>, '_ih': ['', '# 认为a1是全局的\na1 = 100\n\ndef fun():\n    print(a1)\n    print("I am in fun")\n    a2 = 99\n    print(a2)\n    \nprint(a2)', '# 认为a1是全局的\na1 = 100\n\ndef fun():\n    print(a1)\n    print("I am in fun")\n    a2 = 99\n    print(a2)\n    \nprint(a1)', '# 认为a1是全局的\na1 = 100\n\ndef fun():\n    print(a1)\n    print("I am in fun")\n    a2 = 99\n    print(a2)\n    \nprint(a1)\nfun()\n# print(a2)', '# 认为a1是全局的\na1 = 100\n\ndef fun():\n    print(a1)\n    print("I am in fun")\n    a2 = 99\n    print(a2)\n    \nprint(a1)\nfun()\nprint(a2)', '# 认为a1是全局的\na1 = 100\n\ndef fun():\n    print(a1)\n    print("I am in fun")\n    a2 = 99\n    print(a2)\n    \nprint(a1)\nfun()\n# print(a2)', 'def fun():\n    b1 = 100\n    print(b1)\n    print("I am in fun")\n    b2 = 99\n    print(b2)\n    \nfun()', 'def fun():\n    global b1 = 100\n    print(b1)\n    print("I am in fun")\n    b2 = 99\n    print(b2)\n\nprint(b1)', 'def fun():\n    global b1 \n    b1 = 100\n    print(b1)\n    print("I am in fun")\n    b2 = 99\n    print(b2)\n\nprint(b1)', 'def fun():\n    global b1 \n    b1 = 100\n    print(b1)\n    print("I am in fun")\n    b2 = 99\n    print(b2)\n\nprint(b1)', 'def fun():\n    global b1 \n    b1 = 100\n    print(b1)\n    print("I am in fun")\n    b2 = 99\n    print(b2)\n\nprint(b1)', '# globals 和 locals\na = 1\nb = 2\n\ndef fun(c,d):\n    e = 111\n    print("Locals={0}".format(locals()))\n    print("Globals={0}".format(globals())\n          \nfun(100, 200)', '# globals 和 locals\na = 1\nb = 2\n\ndef fun(c,d):\n    e = 111\n    print("Locals={0}".format(locals()))\n    print("Globals={0}".format(globals()))\n          \nfun(100, 200)', '# globals 和 locals\n# globals 和 locals 叫做内建函数\na = 1\nb = 2\n\ndef fun(c,d):\n    e = 111\n    print("Locals={0}".format(locals()))\n    print("Globals={0}".format(globals()))\n          \nfun(100, 200)'], '_oh': {}, '_dh': ['d:\\Jupyter\\nootbook\\笔记'], 'In': ['', '# 认为a1是全局的\na1 = 100\n\ndef fun():\n    print(a1)\n    print("I am in fun")\n    a2 = 99\n    print(a2)\n    \nprint(a2)', '# 认为a1是全局的\na1 = 100\n\ndef fun():\n    print(a1)\n    print("I am in fun")\n    a2 = 99\n    print(a2)\n    \nprint(a1)', '# 认为a1是全局的\na1 = 100\n\ndef fun():\n    print(a1)\n    print("I am in fun")\n    a2 = 99\n    print(a2)\n    \nprint(a1)\nfun()\n# print(a2)', '# 认为a1是全局的\na1 = 100\n\ndef fun():\n    print(a1)\n    print("I am in fun")\n    a2 = 99\n    print(a2)\n    \nprint(a1)\nfun()\nprint(a2)', '# 认为a1是全局的\na1 = 100\n\ndef fun():\n    print(a1)\n    print("I am in fun")\n    a2 = 99\n    print(a2)\n    \nprint(a1)\nfun()\n# print(a2)', 'def fun():\n    b1 = 100\n    print(b1)\n    print("I am in fun")\n    b2 = 99\n    print(b2)\n    \nfun()', 'def fun():\n    global b1 = 100\n    print(b1)\n    print("I am in fun")\n    b2 = 99\n    print(b2)\n\nprint(b1)', 'def fun():\n    global b1 \n    b1 = 100\n    print(b1)\n    print("I am in fun")\n    b2 = 99\n    print(b2)\n\nprint(b1)', 'def fun():\n    global b1 \n    b1 = 100\n    print(b1)\n    print("I am in fun")\n    b2 = 99\n    print(b2)\n\nprint(b1)', 'def fun():\n    global b1 \n    b1 = 100\n    print(b1)\n    print("I am in fun")\n    b2 = 99\n    print(b2)\n\nprint(b1)', '# globals 和 locals\na = 1\nb = 2\n\ndef fun(c,d):\n    e = 111\n    print("Locals={0}".format(locals()))\n    print("Globals={0}".format(globals())\n          \nfun(100, 200)', '# globals 和 locals\na = 1\nb = 2\n\ndef fun(c,d):\n    e = 111\n    print("Locals={0}".format(locals()))\n    print("Globals={0}".format(globals()))\n          \nfun(100, 200)', '# globals 和 locals\n# globals 和 locals 叫做内建函数\na = 1\nb = 2\n\ndef fun(c,d):\n    e = 111\n    print("Locals={0}".format(locals()))\n    print("Globals={0}".format(globals()))\n          \nfun(100, 200)'], 'Out': {}, 'get_ipython': <bound method InteractiveShell.get_ipython of <ipykernel.zmqshell.ZMQInteractiveShell object at 0x000001B07AF18BA8>>, 'exit': <IPython.core.autocall.ZMQExitAutocall object at 0x000001B07D7398D0>, 'quit': <IPython.core.autocall.ZMQExitAutocall object at 0x000001B07D7398D0>, '_': '', '__': '', '___': '', '_i': '# globals 和 locals\na = 1\nb = 2\n\ndef fun(c,d):\n    e = 111\n    print("Locals={0}".format(locals()))\n    print("Globals={0}".format(globals()))\n          \nfun(100, 200)', '_ii': '# globals 和 locals\na = 1\nb = 2\n\ndef fun(c,d):\n    e = 111\n    print("Locals={0}".format(locals()))\n    print("Globals={0}".format(globals())\n          \nfun(100, 200)', '_iii': 'def fun():\n    global b1 \n    b1 = 100\n    print(b1)\n    print("I am in fun")\n    b2 = 99\n    print(b2)\n\nprint(b1)', '_i1': '# 认为a1是全局的\na1 = 100\n\ndef fun():\n    print(a1)\n    print("I am in fun")\n    a2 = 99\n    print(a2)\n    \nprint(a2)', 'a1': 100, 'fun': <function fun at 0x000001B07D8C41E0>, '_i2': '# 认为a1是全局的\na1 = 100\n\ndef fun():\n    print(a1)\n    print("I am in fun")\n    a2 = 99\n    print(a2)\n    \nprint(a1)', '_i3': '# 认为a1是全局的\na1 = 100\n\ndef fun():\n    print(a1)\n    print("I am in fun")\n    a2 = 99\n    print(a2)\n    \nprint(a1)\nfun()\n# print(a2)', '_i4': '# 认为a1是全局的\na1 = 100\n\ndef fun():\n    print(a1)\n    print("I am in fun")\n    a2 = 99\n    print(a2)\n    \nprint(a1)\nfun()\nprint(a2)', '_i5': '# 认为a1是全局的\na1 = 100\n\ndef fun():\n    print(a1)\n    print("I am in fun")\n    a2 = 99\n    print(a2)\n    \nprint(a1)\nfun()\n# print(a2)', '_i6': 'def fun():\n    b1 = 100\n    print(b1)\n    print("I am in fun")\n    b2 = 99\n    print(b2)\n    \nfun()', '_i7': 'def fun():\n    global b1 = 100\n    print(b1)\n    print("I am in fun")\n    b2 = 99\n    print(b2)\n\nprint(b1)', '_i8': 'def fun():\n    global b1 \n    b1 = 100\n    print(b1)\n    print("I am in fun")\n    b2 = 99\n    print(b2)\n\nprint(b1)', '_i9': 'def fun():\n    global b1 \n    b1 = 100\n    print(b1)\n    print("I am in fun")\n    b2 = 99\n    print(b2)\n\nprint(b1)', '_i10': 'def fun():\n    global b1 \n    b1 = 100\n    print(b1)\n    print("I am in fun")\n    b2 = 99\n    print(b2)\n\nprint(b1)', '_i11': '# globals 和 locals\na = 1\nb = 2\n\ndef fun(c,d):\n    e = 111\n    print("Locals={0}".format(locals()))\n    print("Globals={0}".format(globals())\n          \nfun(100, 200)', '_i12': '# globals 和 locals\na = 1\nb = 2\n\ndef fun(c,d):\n    e = 111\n    print("Locals={0}".format(locals()))\n    print("Globals={0}".format(globals()))\n          \nfun(100, 200)', 'a': 1, 'b': 2, '_i13': '# globals 和 locals\n# globals 和 locals 叫做内建函数\na = 1\nb = 2\n\ndef fun(c,d):\n    e = 111\n    print("Locals={0}".format(locals()))\n    print("Globals={0}".format(globals()))\n          \nfun(100, 200)'}

    eval()函数

    把一个字符串当成一个表达式来执行,返回表达式执行后的结果

    语法:

              eval(string_code, globals=None, locals=None)

    exec()函数

    跟eval功能类似,但是,不返回结果

    语法:

              exec(string_code, globals=None, locals=None)

    x = 100
    y = 200
    # 执行x+y
    # z = x + y
    z1 = x + y
    z2 = eval("x+y")
    
    print(z1)
    print(z2)
    

    300
    300

    # exec案例
    x = 100
    y = 200
    # 执行x+y
    # z = x + y
    z1 = x + y
    # 1. 注意字符串中引号的写法
    # 2. 比对exec执行结果和代码执行结果
    z2 = exec("print('x+y:',x+y)")
    
    print(z1)
    print(z2)
    

    x+y: 300
    300
    None

    递归函数

    • 函数直接或者间接调用自身
    • 优点:简洁,理解容易
    • 缺点:对递归深度有限制,消耗资源大
    • python对递归深度有限制,超过限制报错
    • 在写递归程序的时候,一定注意结束条件
    # 递归调用深度限制代码
    
    x = 0
    def fun():
     global x
     x += 1
     print(x)
     # 函数自己调用自己
     fun()
     
    # 调用函数
    # fun()
    

    ---------------------------------------------------------------------------

    RecursionError                            Traceback (most recent call last)

    <ipython-input-23-bfedb7e396bc> in <module>
         10
         11 # 调用函数
    ---> 12 fun()


    <ipython-input-23-bfedb7e396bc> in fun()
          7     print(x)
          8     # 函数自己调用自己
    ----> 9     fun()
         10
         11 # 调用函数


    ... last 1 frames repeated, from the frame below ...


    <ipython-input-23-bfedb7e396bc> in fun()
          7     print(x)
          8     # 函数自己调用自己
    ----> 9     fun()
         10
         11 # 调用函数


    RecursionError: maximum recursion depth exceeded while calling a Python object

    # 斐波那契数列
    # 一列数字,第一个值是1,第二个也是1,从第三个开始,每一个数字的值等于前两个数字出现的值的和
    # 数学公式为: f(1) = 1, f(2) = 1, f(n) = f(n - 1) + f(n - 2)
    # 例如: 1,1,2,3,5,8,13....
    
    # n表示求第n个数字的斐波那契数列的值
    def fib(n):
     if n == 1 or n == 2:
      return 1
     elif n > 0:
      return fib(n-1) + fib(n-2)
     else:
      return None
    
    print(fib(3))
    print(fib(5))
    print(fib(10))
    print(fib(-1))
    print(fib(1))
    

    2
    5
    55
    None
    1

    内置数据结构(变量类型)

    • list
    • set
    • dict
    • tuple

    list(列表)

    一组有顺序的数据的组合

    创建列表

    • 空列表
    # 1. 创建空列表
    l1 = []
    # type是内置函数,负责打印出变量的类型
    print(type(l1))
    print(l1)
    
    # 2. 创建带值的列表
    l2 = [100]
    print(type(l2))
    print(l2)
    
    # 3. 创建列表,带多个值
    l3 = [2,3,5,5,9,7,8,]
    print(type(l3))
    print(l3)
    
    # 4. 使用list()
    l4 = list()
    print(type(l4))
    print(l4)
    

    <class 'list'>
    []
    <class 'list'>
    [100]
    <class 'list'>
    [2, 3, 5, 5, 9, 7, 8]
    <class 'list'>
    []

    列表常用操作

    访问

    • 使用下标操作(索引)
    • 列表的位子是从0开始

    分片操作

    • 对列表进行任意一段的截取
    • l[:]
    # 下标访问列表
    l = [3,2,5,1,9,8,7]
    
    print(l[1])
    

    2

    print(l[0])
    

    3

    # 分片操作
    # 注意截取的范围,包含左边的下标值,不包含右边的下标值
    print(l[1:4])
    
    # 下标值可以为空,如果不写,左边下标值默认为0,右边下标值为最大数加一,即表示截取到最后一个数据
    print(l[:])
    print(l[:4])
    print(l[2:])
    
    

    [2, 5, 1]
    [3, 2, 5, 1, 9, 8, 7]
    [3, 2, 5, 1]
    [5, 1, 9, 8, 7]

    print(l)
    # 分片可以控制增长幅度,默认增长幅度为1
    print(l[1:6:1])
    
    # 打印从下标1开始的数字,每次隔一个
    print(l[1:6:2])
    
    # 下标可以超出范围,超出后不在考虑多余下标内容
    print(l[2:10])
    
    # 下标值,增长幅度可以为负数
    # 为负数,表明为从右往左
    # 规定: 数组最后一个数字的下标是-1
    

    [3, 2, 5, 1, 9, 8, 7]
    [2, 5, 1, 9, 8]
    [2, 1, 8]
    [5, 1, 9, 8, 7]

    # 分片之负数下标
    print(l)
    
    # 下面显示的是为空,因为默认分片总是从左向右截取
    print(l[-2:-4])
    print(l[-4:-2])
    
    # 如果分片一定左边值比右边大,则步长参数需要使用负数
    # 此案例为一个list直接正反截取提供了一个思路
    print(l[-2:-4:-1])
    print(l[-1:-8:-1])
    

    [3, 2, 5, 1, 9, 8, 7]
    []
    [1, 9]
    [8, 9]
    [7, 8, 9, 1, 5, 2, 3]

    分片操作是生成一个新的list

    内置函数id,负责显示一个变量或者数据的唯一确定编号

    # id函数举例
    a = 100
    b = 200
    print(id(a))
    print(id(b))
    
    # a跟c指向同一份数据
    c = a
    print(id(c))
    
    a = 101
    print(a)
    print(c)
    
    print(id(a))
    print(id(c))
    

    140734817148832
    140734817152032
    140734817148832
    101
    100
    140734817148864
    140734817148832

    # 通过id可以直接判断出分片是重新生成了一份数据还是使用同一份数据
    l = [3,5,6,8,5,43,4,7]
    ll = l[:]  # 分片操作
    lll = ll
    # 如果两个id值一样,则表明分片产生的列表是使用的同一地址同一份数据
    # 否则,则表明分片是重新产生了一份数据,即一个新的列表,然后把数据拷贝到新列表中
    print(id(l))
    print(id(ll))
    print(id(lll))
    
    # 通过id知道,ll和lll是同一份数据,验证代码如下
    l[1] = 100
    print(l)
    print(ll)
    print(lll)
    
    ll[1] = 100
    print(ll)
    print(lll)
    

    1857540073800
    1857540052488
    1857540052488
    [3, 100, 6, 8, 5, 43, 4, 7]
    [3, 5, 6, 8, 5, 43, 4, 7]
    [3, 5, 6, 8, 5, 43, 4, 7]
    [3, 100, 6, 8, 5, 43, 4, 7]
    [3, 100, 6, 8, 5, 43, 4, 7]

    总结

    jsjbwy
    下一篇:没有了