不要把自己活得像落难者一样,急着告诉所有人你的不幸。总有一天你会发现,酸甜苦辣要自己尝,漫漫人生要自己过,你所经历的在别人眼里都是故事,也别把所有的事都掏心掏肺的告诉别人,成长本来就是一个孤立无援的过程,你要努力强大起来,然后独当一面!
总结:
- 使用相对导入的主模块不能再当作主模块运行;
- Python中就没有什么是藏得住的,你都可以改(特别是对于模块来讲)
1. 绝对导入、相对导入
绝对导入
在import语句或者from导入模块,模块名称最前面不是以.点开头的
绝对导入总是去模块搜索路径中找,当然会查看一下该模块是否已经加载
相对导入
只能在包内使用,且只能用在from语句中
使用.点号,表示当前目录内
..表示上一级目录
不要在顶层模块中使用相对导入
举例a.b.c模块,c是模块,c的代码中,使用
from . import d # imports a.b.d
from .. import e # imports a.e
from .d import x # a.b.d.x
from ..e import x # a.e.x
... 三点表示上上一级
使用下面结构的包,体会相对导入的使用
注意:一旦一个模块中使用相对导入,就不可以作为主模块运行了
2. 访问控制
下划线开头的模块名
_ 或者 __ 开头的模块是否能够被导入呢?
创建文件名为 _xyz.py 或者 __xyz.py 测试
都可以成功的导入,因为它们都是合法的标识符,就可以用作模块名
模块内的标识符
# xyz.py
print(__name__)
A = 5
_B = 6
__C = 7
__my__ = 8
# test.py中
import xyz
import sys
print(sorted(sys.modules.keys()))
print(dir())
print(xyz.A, xyz._B, xyz.__C, xyz.__my__)
普通变量、保护变量、私有变量、特殊变量,都没有被隐藏,也就是说模块内没有私有的变量,在模块中定义不做特殊处理。
使用from ... import *
# xyz.py
print(__name__)
A = 5
_B = 6
__C = 7
__my__ = 8
# test.py中
from xyz import *
import sys
print(sorted(sys.modules.keys()))
print(dir())
print(locals()['A'])
A = 55
print(locals()['A']) # 思考这个A是谁的A了
使用 _all_
_all_ 是一个列表,元素是字符串,每一个元素都是一个模块内的变量名
总结
一、使用 from xyz import * 导入
- 如果模块没有 all , from xyz import * 只导入非下划线开头的该模块的变量。如果是包,子模块也不会导入,除非在 all 中设置,或 init.py 中导入它们;
- 如果模块有 all , from xyz import * 只导入 all 列表中指定的名称,哪怕这个名词是下划线开头的,或者是子模块;
- from xyz import * 方式导入,使用简单,但是其副作用是导入大量不需要使用的变量,甚至有可能造成名称的冲突。而 all 可以控制被导入模块在这种导入方式下能够提供的变量名称,就是为了阻止from xyz ;import *导入过多的模块变量,从而避免冲突。因此,编写模块时,应该尽量加入 all;
二、from module import name1, name2 导入
这种方式的导入是明确的,哪怕是导入子模块,或者导入下划线开头的名称;
3. 模块变量的修改
模块对象是同一个,因此模块的变量也是同一个,对模块变量的修改,会影响所有使用者。
除非万不得已,或明确知道自己在做什么,否则不要修改模块的变量。
前面学习过的猴子补丁,也可以通过打补丁的方式,修改模块的变量、类、函数等内容。
# xyz.py
print(__name__)
X = 10
# test2.py
import xyz
print(xyz.X)
# test.py
import xyz
print(xyz.X)
xyz.X = 50
import test2
网友评论