• python import xx和from xx import x 中的坑


    先回顾一下理解程度

    什么是不可变类型和可变类型?

      可变类型是,修改变量后 引用的内存地址不变,引用的内存中的内容发生变化(是针对变量名的引用来理解)。

    # 在a.py中定义了一个test属性
    test = [1, 2]
    print(test ,id(test))
    test.append('jack')
    print(test, id(test))
    
    
    结果
    C:UsersjackendoffAppDataLocalProgramsPythonPython36-32python.exe D:/pycharm_project/test_import/a.py
    [1, 2] 44687112
    [1, 2, 'jack'] 44687112
    
    Process finished with exit code 0
    可变类型

      不可变类型,修改变量后,内存地址发生变化,引用的内容也发生变化(针对变量名的引用理解),(如int类型再内存中的存储id是固定的,不同的数字存储的位置是确定的)

    # 在a.py中定义了一个test属性
    test = 5
    print(test, id(test))
    test = 6
    print(test, id(test))
    
    
    结果
    C:UsersjackendoffAppDataLocalProgramsPythonPython36-32python.exe D:/pycharm_project/test_import/a.py
    5 1795613520
    6 1795613536
    
    Process finished with exit code 0
    不可变类型

     

     下面写四个脚本,验证import的 导入对象的属性 是不可变类型的修改,jia.py是导入了b.py和c.py两个模块,并运行,(千万不要起abc.py,它是内置模块)

    1 # 在a.py中定义了一个test属性
    2 test = 2
    3 print('in a')
    a.py
    import a
    # 引用了a.py模块,是整个模块的引用
    print('first print in b.py', a.test)
    a.test = 3
    print('second print in b.py', a.test)
    
    ''' 注意区分模块和包的含义
        模块就是一个x.py的程序
        包是包含许多xx.py程序的文件夹(该文件夹中必须有__init__.py程序)
    '''
    b.py
    import a
    # 引用了a.py模块
    print('first print in c.py', a.test)
    
    a.test = 4
    print('second print in c.py', a.test)
    c.py
    # abc.py是python内置模块的名字,脚本名字别乱起
    import b
    import c
    print('first print in jia.py', b.a.test)
    print('second print in jia.py', c.a.test)
    jia.py
    C:UsersjackendoffAppDataLocalProgramsPythonPython36-32python.exe D:/pycharm_project/test_import/jia.py
    in a
    first print in b.py 2
    second print in b.py 3
    first print in c.py 3
    second print in c.py 4
    first print in jia.py 4
    second print in jia.py 4
    
    Process finished with exit code 0
    jia.py的运行结果

     b.py中second print和c.py中first print输出都是3,说明b.py已经修改了模块的属性

    下面再写四个脚本,验证from xx import x 能不能对模块的不可变类型属性修改,jia.py是导入了b.py和c.py两个模块,并运行。

    # 在a.py中定义了一个test属性
    test = 2
    print('in a')
    a.py
    from a import *
    # 引用了a.py模块,是整个模块的引用
    print('first print in b.py', test)
    test = 3
    print('second print in b.py', test)
    b.py
    from a import *
    # 引用了a.py模块
    print('first print in c.py', test)
    
    test = 4
    print('second print in c.py', test)
    c.py
    # abc.py是python内置模块的名字,脚本名字别乱起
    import b
    import c
    print('first print in jia.py', b.test)
    print('second print in jia.py', c.test)
    jia,py
    C:UsersjackendoffAppDataLocalProgramsPythonPython36-32python.exe D:/pycharm_project/test_import/jia.py
    in a
    first print in b.py 2
    second print in b.py 3
    first print in c.py 2
    second print in c.py 4
    first print in jia.py 3
    second print in jia.py 4
    
    Process finished with exit code 0
    jia.py的运行结果

     b.py中second print和c.py中first print输出一个是3一个是2,说明b.py没有修改了模块的属性

    下面再写四个脚本,验证from xx import x 能不能对模块的可变类型属性修改,jia.py是导入了b.py和c.py两个模块,并运行。

    # 在a.py中定义了一个test属性
    test = [1, 2]
    print('in a')
    a.py
    from a import *
    # 引用了a.py模块,是整个模块的引用
    print('first print in b.py', test)
    test.append('b')
    print('second print in b.py', test)
    
    ''' 注意区分模块和包的含义
        模块就是一个x.py的程序
        包是包含许多xx.py程序的文件夹(该文件夹中必须有__init__.py程序)
    '''
    b.py
    from a import *
    # 引用了a.py模块
    print('first print in c.py', test)
    
    test.append('c')
    print('second print in c.py', test)
    c.py
    # abc.py是python内置模块的名字,脚本名字别乱起
    import b
    import c
    print('first print in jia.py', b.test)
    print('second print in jia.py', c.test)
    jia.py
    C:UsersjackendoffAppDataLocalProgramsPythonPython36-32python.exe D:/pycharm_project/test_import/jia.py
    in a
    first print in b.py [1, 2]
    second print in b.py [1, 2, 'b']
    first print in c.py [1, 2, 'b']
    second print in c.py [1, 2, 'b', 'c']
    first print in jia.py [1, 2, 'b', 'c']
    second print in jia.py [1, 2, 'b', 'c']
    
    Process finished with exit code 0
    jia.py的运行结果

    b.py中second print 和 c.py中first print 输出的都是[1, 2, 'b'],说明b.py已经修改了模块的属性

    总结:使用import xx 可以修改模块对象的属性(无论属性是不是可变类型)

          使用from xx import x 只能修改模块对象的属性是可变类型的(不可变类型不能修改)

    这也是为甚麽,尽量不要使用 from XX import * 的原因,会发生属性错误,

    这也是为什么,导入模块需要写在程序开头的位置,并且先导入内置模块,再导入库模块,再导入自定义模块

  • 相关阅读:
    一个简单的CSS3+js 实现3D BOX
    jquery $.extend()扩展插件获取焦点或失去焦点事件
    菜单滑动
    全选反选
    纯css,编写菜单移入效果
    登录窗口抖动效果
    [WCF]WCF起航
    FastReport 数据过滤
    [Oracle]TRIGGER
    两种递归方法的比较
  • 原文地址:https://www.cnblogs.com/serpent/p/9454130.html
Copyright © 2020-2023  润新知