代码改变世界

第二十二章 模块代码编写基础

2017-04-13 20:29  szn好色仙人  阅读(240)  评论(0编辑  收藏  举报
#1.
#A:因为模块名在python中会变成变量名,因此模块名需要遵守python的命名规则,否则无法将其导入(定义一个if.py,则无法导入)
#B:当一个模块被导入的时候,python会把内部模块名映射到外部文件名,会将模块搜索路径中的目录路径加在前面,而.py或者其他后缀名加在后面
#C:import会读取整个模块,所以必须进行定义后才能读取它的变量名,from会将变量名复制到另一个作用域,所以她就可以让我们直接使用复制后的变量名而不需要通过模块
#D:from语句其实只是稍稍扩展了import语句而已,她照常导入了模块文件,但是多了一个步骤:将文件中的一个或多个变量名从文件中复制了出来
#E:from*,会取得模块顶层所有赋值了的变量名的拷贝,也是照常导入了模块文件,但是多了复制所有变量到导入的作用域之内的步骤

#2.
'''
就像def一样,import和from是可执行语句,而不是编译期间的声明,而且她们可以嵌套在if测试中,出现在函数def之中等,直到执行程序时,python执行到这些语句,
才会进行解析。就像def一样,import和from都是隐式的赋值语句,import将整个模块对象赋值给一个变量名,from将一个或多个变量名赋值给另一个模块中的同名对象
'''

#3.
#A:以from复制的变量会变成对共享对象的引用,这个行为就和python的函数传参一样
#B:为了实际修改另一个模块内的全局变量,必须使用import
'''
Test.py内容:
L0 = []
valueTest = 10

def FunTest():
    return L0, valueTest
'''

from Test import L0, valueTest, FunTest
value0 = FunTest()          #value0 = ([], 10)
L0.append(10)               #由于模块Test内的L0是可变对象,所以这句代码会影响Test模块内的L0
valueTest = 'a'             #注意点:这句代码并没有改变Test模块内的valueTest变量
value1 = FunTest()          #value1 = ([10], 10)
L0 = 'b'
value2 = FunTest()          #value2 = ([10], 10)

import Test
Test.L0 = 'a'
Test.valueTest = 'b'
value3 = FunTest()          #value3 = ('a', 'b')

#4.
#A:在模块文件顶层每一个赋值了的变量名都会变成该模块的属性
#B:模块的命名空间能通过属性__dict__或者dir(M)获取
value0 = Test.__dict__  
'''
value0 = 
{'FunTest': <function FunTest at...002DE09D8>, 'L0': 'a', '__builtins__': {'ArithmeticError': <class 'ArithmeticError'>, 
'AssertionError': <class 'AssertionError'>, 'AttributeError': <class 'AttributeError'>, 'BaseException': <class 'BaseException'>, 'Block...
'''

value1 = dir(Test)      
'''
value1 = ['FunTest', 'L0', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'valueTest']
'''

#5.
#A:模块可以互相导入
'''
Test1.py内容:
import Test2
valueTest1 = 'Test1'

Test2.py内容:
import Test1
valueTest2 = 'Test2'
'''

import Test1
import Test2
value0 = Test1.valueTest1           #value0 = 'Test1'
value1 = Test2.valueTest2           #value1 = 'Test2'
value2 = Test1.Test2.valueTest2     #value2 = 'Test2'
value3 = Test2.Test1.valueTest1     #value3 = 'Test1'

#6.
#A:reload函数会强制已加载的模块的代码重新载入并重新执行。此文件中的新的代码的赋值语句会在适当的地方修改现有的模块对象
#B:reload存在于模块imp中,是一个内置函数,程序中任何引用该模块的地方,自动会受到reload的影响。
#C:reload之后,对于原先使用from引用的对象,其引用的对象仍然是旧对象
'''
Test3.py内容:
print("Begin Import Test3", end = '---')

L0 = []
valueTest = 10

print("End Import Test3")
'''

from Test3 import L0, valueTest, FunTest    #输出:Begin Import Test3---End Import Test3
import Test3                                #并没有输出
value0 = L0                                 #value0 = []
value1 = Test3.valueTest                    #value1 = 10

'''
打个断点,将Test3.py内容修改为:
print("Begin Import Test3", end = '---')

L0 = 'a'
valueTest = 'b'

print("End Import Test3")
'''
from imp import reload
reload(Test3)                               #输出:Begin Import Test3---End Import Test3
tuple0 = value0, value1                     #tuple0 = ([], 10)
value0 = L0                                 #value0 = []
value1 = Test3.valueTest                    #value1 = 'b'

from Test3 import L0, valueTest, FunTest    #并没有输出
value0 = L0                                 #value0 = 'a'