只要不是以.开头的,都是绝对导入,绝对导入总是去搜索路径中找,当然会查看一下该模块是否已经加载
import语句是不允许相对导入的,只能使用from
所以这么做,当前平级的有m1,m2
使用了相对导入的模块,不能再作为主模块运行了
创建这几个包
这么写可以
。。。表示上上一级
import只支持绝对导入,绝对m1,就需要去sys.modules里查看m1有没有加载,结果sys.modules里没有m1,然后找到sys.path里逐个去找
(sys.path不进子目录去找,有几个目录列几个目录,目录不递归查找)
当前目录只能看到m,m.m1和m1是两码事,所以现在找的是顶层模块的m1,所以找不到
试试相对导入,from语句支持,在包内使用,代码位置都不用动
在项目的根目录下用相对路径意义不大,基本上都是import,相对导入都是用在内部的,包里的
假如没有导入
这是m自己收集自己的
这句执行会在当前环境多m1
生成两个文件
是可以绝对导入的,所以这种规则对模块无用
还是用t1和t2做,试试这样能否访问到,这些变量相当于模块的属性,
__z按照原来是私有成员
使用绝对导入,能否访问到
所以以前的私有属性,只试用于类,类属性和实例属性只要是__双下划线开头,称为私有的,私有的类变量和私有的实例变量都会被改名
_单下划线是保护的
模块内没有私有的变量,不做特殊处理
换一种写法
全改名
import 星号,代表从这个模块导入非下划线开头的
为了在t看到t2,在t2加上这么写
t模块只是把x导入进来
t2修改
凡是下划线开头的一概不导入
** _make_key,functools里的,这就是不想给你使用*
*import ,这样是绝对不会找到_make_key,别人的意思就是自己用不是给你使用的
但是非要导入也拦不住你
这个 * ,替你拿到了模块中,非下划线开头的所有成员,导入到当前命名空间中供你使用
这个变量对于模块来说很特殊
t2的东西都没有了
加个x
现在就有了
多了个a
调用一下a
指定带下划线的
** z的 值是3,没有问题**
**如果没有__all__这个属性,import * 会把所有非下划线开头的导入,如果有__all,只要是你管的成员,放谁过去由__all__说了算**
虽然有__all__但是也控制不住你这样拿东西
查看标准库pathlib里的使用
怕人import *这样导入你的模块,你最好加一个__all__
这里还实现了slots相当于定义实例能够用哪些属性,然后把自己实例的字典去掉了,当你有很多实例的时候可以节约内存
、
这个是两个文件,在test中导入了xyz的 * ,下面用locals访问 [A],
locals当前模块,而import已经把xyz里的都导入进来了
对m下的init进行修改
把m1也修改了
在t中如何访问
现在import m的时候没有把m1导入,m.m1是访问不到的
这么写即可,
impot m是就加载m模块,m1没人加载,问你m。m1.y是找不到的
下面的写法,import m.m1顺便把m和m1都加载了,但是只能看到顶层模块
怕出错可以这么写
可以用from语句,这两行说明m一定加载,发现m1又是个模块,就会也加进去,这样就两个都加载,把这个名词放入当前名词空间当中,所以使用m1.y
还有的访问方式
试试这样
m是init打印出来的,导入成功,到下面m.m1.y就失败了
** all__只是在宣称当前下面有哪些属性可以公布出去,但是属性在不在就管不着
现在试试让init里面能看到m1**
不要__all__试试m1能否访问到
在init里面相当于就是m1在包里面,是可以访问到的
恢复一下
**主要是对 from m import *有很多影响,在m里有__all,**
试试相对导入,相对导入是无法作为主模块运行的
作为被导入模块就没有影响
一旦出现了相对导入的情况,那个模块就只能变成被导入模块,在包里使用相对导入的目的就是,外面随便改变,包里的关系不变,这样就是为了以后包想放哪里就放哪里
导入是加入到本地名词空间,加载谁看sys.modules,看有没有加载进去
*1.如果模块没有_ all_ , from xyz import 只导入非下划线开头的该模块的变量。如果是包,子模块也不会导入,除非在_ all_ 中设置, 或_init_ .py 中导入它们
*2.如果模块有_ all , from xyz import 只导入_ all (里面写了什么就是什么)列表中指定的名称 ,哪怕这个名词是下划线开头的,或者是子模块。
**3. from xyz import 方式导入,使用简单,但是其副作用是导入大量不需要使用的变量(不以下划线开头的全进来了),甚至有可能造成名称的冲突。而_ all 可以控制被导 入模块在这种导入方式下能够提供的变量名称,就是为了阻止from xyz import 导入过多的模块变量,从而避免冲突。因此,编写模块时,应该尽量加入_all_
模块里面所有顶层的方法其实 都是要导入的,这里面的类都要创建类对象出来,里面的函数创建函数对象,模块过大就拆成包,组成多个.py文件
t里定义x=100
t2
t1
模块是同一个对象,但是修改了模块的同一个变量,你在修改,别人在用,除非万不得已,不要修改模块中的定义
猴子补丁也是来修改类,函数
可以顶掉
模块和包说白了就是对代码进行封装,模块可以使用的时候,绝对导入和相对导入,模块内部建议使用相对导入,在外面试用包的使用建议使用绝对导入,使用什么就需要控制,哪些可以访问哪些不可以访问