先回顾一下理解程度
什么是不可变类型和可变类型?
可变类型是,修改变量后 引用的内存地址不变,引用的内存中的内容发生变化(是针对变量名的引用来理解)。
# 在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')
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程序) '''
import a # 引用了a.py模块 print('first print in c.py', a.test) a.test = 4 print('second print in c.py', a.test)
# 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)
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
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')
from a import * # 引用了a.py模块,是整个模块的引用 print('first print in b.py', test) test = 3 print('second print in b.py', test)
from a import * # 引用了a.py模块 print('first print in c.py', test) test = 4 print('second print in c.py', test)
# abc.py是python内置模块的名字,脚本名字别乱起 import b import c print('first print in jia.py', b.test) print('second print in jia.py', c.test)
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
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')
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程序) '''
from a import * # 引用了a.py模块 print('first print in c.py', test) test.append('c') print('second print in c.py', test)
# abc.py是python内置模块的名字,脚本名字别乱起 import b import c print('first print in jia.py', b.test) print('second print in jia.py', c.test)
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
b.py中second print 和 c.py中first print 输出的都是[1, 2, 'b'],说明b.py已经修改了模块的属性
总结:使用import xx 可以修改模块对象的属性(无论属性是不是可变类型)
使用from xx import x 只能修改模块对象的属性是可变类型的(不可变类型不能修改)
这也是为甚麽,尽量不要使用 from XX import * 的原因,会发生属性错误,
这也是为什么,导入模块需要写在程序开头的位置,并且先导入内置模块,再导入库模块,再导入自定义模块