先回顾一下理解程度
什么是不可变类型和可变类型?
可变类型是,修改变量后 引用的内存地址不变,引用的内存中的内容发生变化(是针对变量名的引用来理解)。
#在a.py中定义了一个test属性
test = [1, 2]print(test ,id(test))
test.append('jack')print(test, id(test))
结果
C:\Users\jackendoff\AppData\Local\Programs\Python\Python36-32\python.exe D:/pycharm_project/test_import/a.py
[1, 2] 44687112[1, 2, 'jack'] 44687112Process finished with exit code 0
可变类型
不可变类型,修改变量后,内存地址发生变化,引用的内容也发生变化(针对变量名的引用理解),(如int类型再内存中的存储id是固定的,不同的数字存储的位置是确定的)
#在a.py中定义了一个test属性
test = 5
print(test, id(test))
test= 6
print(test, id(test))
结果
C:\Users\jackendoff\AppData\Local\Programs\Python\Python36-32\python.exe D:/pycharm_project/test_import/a.py5 1795613520
6 1795613536Process 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
importa#引用了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
importa#引用了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内置模块的名字,脚本名字别乱起
importbimportcprint('first print in jia.py', b.a.test)print('second print in jia.py', c.a.test)
jia.py
C:\Users\jackendoff\AppData\Local\Programs\Python\Python36-32\python.exe D:/pycharm_project/test_import/jia.pyina
firstprint in b.py 2secondprint in b.py 3firstprint in c.py 3secondprint in c.py 4firstprint in jia.py 4secondprint in jia.py 4Process 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内置模块的名字,脚本名字别乱起
importbimportcprint('first print in jia.py', b.test)print('second print in jia.py', c.test)
jia,py
C:\Users\jackendoff\AppData\Local\Programs\Python\Python36-32\python.exe D:/pycharm_project/test_import/jia.pyina
firstprint in b.py 2secondprint in b.py 3firstprint in c.py 2secondprint in c.py 4firstprint in jia.py 3secondprint in jia.py 4Process 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内置模块的名字,脚本名字别乱起
importbimportcprint('first print in jia.py', b.test)print('second print in jia.py', c.test)
jia.py
C:\Users\jackendoff\AppData\Local\Programs\Python\Python36-32\python.exe D:/pycharm_project/test_import/jia.pyina
firstprint in b.py [1, 2]
secondprint in b.py [1, 2, 'b']
firstprint in c.py [1, 2, 'b']
secondprint in c.py [1, 2, 'b', 'c']
firstprint in jia.py [1, 2, 'b', 'c']
secondprint 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 * 的原因,会发生属性错误,
这也是为什么,导入模块需要写在程序开头的位置,并且先导入内置模块,再导入库模块,再导入自定义模块