zoukankan      html  css  js  c++  java
  • python中可变与不可变类型变量中一些较难理解的地方

    •  当函数内部引用一个全局变量时,如果此全局变量为可变类型,那么函数内部是可以改变此全局变量的值,用不用globale申明全局变量都一样。但是如果想给此变量重新赋值则必须要使用global。
    l = []
    d = {}
    def add_value():
        d['frank'] = 'yangcaho'
        l.append(d)
    add_value()
    print(l)
    print(d)
    
    输出:
    [{'frank': 'yangcaho'}]
    {'frank': 'yangcaho'}
    l = []
    d = {}
    def add_value():
        global l
        global d
        d['frank'] = 'yangcaho'
        l.append(d)
    add_value()
    print(l)
    print(d)
    
    输出:
    [{'frank': 'yangcaho'}]
    {'frank': 'yangcaho'}
    •   当函数内部引用一个全局变量时,如果此全局变量为不可变类型,那么如果要能够在函数内部改变全局变量的值,就需要用global,不用改变则不需要用global也可以引用
    a = 'frank'
    def add_value():
        global a
        a = 'yangchao'
    add_value()
    print(a)
    
    yangchao
    a = 'frank'
    def add_value():
        b = a + 'yangchao'
        print(b)
    add_value()
    print(a)
    
    frankyangchao
    frank

       结论:可以使用定义在函数外的全局变量的值(假设在函数内没有同名的变量)。但强烈建议尽量避免这样做,因为这使得程序的读者会不清楚这个变量是在哪里定义的。使用global语句可以清楚地表明变量是在外面的块定义的。

    一些细微区别

    可变对象如list的.paaend()操作与‘+’操作,的一些不同点。

    • 用 ‘+’ 实际上是重新定义一个变量了。但是原列表的内存位置不会变,会开辟一个新的内存,L不是直接在原来l的基础上增加然后指向l
    l = ['frank', 'liuilu']
    print(id(l))
    L  = l + ['yangchao']
    print(id(L))
    print(l)
    print(id(l))
    
    36364616
    36365960
    ['frank', 'liuilu']
    36364616
    • 用 append 和 ’ += ‘实际上是在原来变量基础上增加。
    l = ['frank', 'liuilu']
    print(id(l))
    l += ['yangchao']
    print(l)
    print(id(l))
    
    43639112
    ['frank', 'liuilu', 'yangchao']
    43639112
    •  一下代码中个很坑的地方:为什么l的值不是[{'age': 1}, {'age': 2}]而是[{'age': 2}, {'age': 2}],因为l中存入的值是d实际是存入了d所指向内存地址。在第二次改变d的值得时候,就是改变了d的指向。于是第一次添加的d的值也会改变。
    l = []
    d = {}
    def add_value():
        for i in range(1, 3):
            print('第%s次循环' %i)
            d['age'] = i
            print(d)
            print('#' * 10)
            print(l)
            print('#' * 10)
            l.append(d)
            print(l)
    add_value()
    
    输出结果
    第1次循环
    {'age': 1}
    ##########
    []
    ##########
    [{'age': 1}]
    第2次循环
    {'age': 2}
    ##########
    [{'age': 2}]
    ##########
    [{'age': 2}, {'age': 2}]

       但是函数内如果是用赋值的方式(如下面两种模式),那么函数中的d就不再是全局变量中的d了。所以有了每次赋值操作(即’=‘),每次append的d都是新的值。不会改变原来的值。

    l = []
    d = {}
    def add_value():
        for i in range(1, 3):
            print('第%s次循环' %i)
            d = {'age', i}
            print(d)
            print('#' * 10)
            print(l)
            print('#' * 10)
            l.append(d)
            print(l)
    add_value()
    
    第1次循环
    {1, 'age'}
    ##########
    []
    ##########
    [{1, 'age'}]
    第2次循环
    {2, 'age'}
    ##########
    [{1, 'age'}]
    ##########
    [{1, 'age'}, {2, 'age'}]
    l = []
    def add_value():
        for i in range(1, 3):
            d = {}
            print('第%s次循环' %i)
            d['age'] = i
            print(d)
            print('#' * 10)
            print(l)
            print('#' * 10)
            l.append(d)
            print(l)
    add_value()
    
    第1次循环
    {'age': 1}
    ##########
    []
    ##########
    [{'age': 1}]
    第2次循环
    {'age': 2}
    ##########
    [{'age': 1}]
    ##########
    [{'age': 1}, {'age': 2}]

       总得来讲就是在操作可变对象的时候,只要有 = 就会重新开辟内存创建新变量,诸如list.append() 、list += 、list.pop、dic.update()、dict['key'] = value、实际上都是在原来变量的基础上作修改,如果后面再次引用则会引用每次修改后的值。

      

    a = []
    b = []
    c = {}
    d = {}
    e = 'frank'
    f = 'frank'
    print(id(a), id(b), id(c), id(d), id(e), id(f))

    43770760 43770824 31284896 31284968 31302408 31302408

       可见每次创建一个空的可变对象时,都会重新开辟内存,但不可变对象就是指向原来的的地址空间。

  • 相关阅读:
    SIP头域说明
    android.os.NetworkOnMainThreadException异常
    "Only the original thread that created a view hierarchy can touch its views"引发的思考_Handler的使用
    sip命令与音视频rtp通话完整流程分析
    在Windows下搭建Android开发环境(摘自百度经验)
    jquery dialog 打开的时候自动聚焦解决方法
    对于数组(字符串)slice方法的总结
    SWIFT语言中的泛型编程 【GENERIC】【PART 2】
    手动调用playground的XCPCaptureValue展示Swift过程数据
    Swift语言相关资源贴
  • 原文地址:https://www.cnblogs.com/yc3110/p/10625235.html
Copyright © 2011-2022 走看看