python导入自定义模块3中 定义的类模块无法导入 提示不能导入

在pycharm中发现模块老是导入不成功

只能以这样的映射的方式

模块的标志符可以由字母、数字、下划线组成但是,

不能以数字开头如果在给python导入自定义模块文件起名时,以數字开头是无法在pycharm中通过导入这个模块的?(自己上面的文件大部分是以数字开头的导致不能导入、、、)

在python导入自定义模块中添加自定义模块

一般来说我们会将自己写的python导入自定义模块模块与python导入自定义模块自带的模块分开存放以达到便于维护的目的。

最近在看《python导入自萣义模块源码剖析》对python导入自定义模块内部运行机制比以前了解的更深入了,感觉自己有机会也可以做个小型的动态脚本语言了呵呵,当然是吹牛了目的当然不是创造一个动态语言,目的只有一个:更好的使用python导入自定义模块看到模块导入那块的时候,终于对模块導入机制比较了解了以防忘记特记录下来。

模块的搜索路径都放在了sys.path列表中如果缺省的sys.path中没有含有自己的模块或包的路径,可以动态嘚加入(sys.path.apend)即可下面是sys.path在Windows平台下的添加规则。

1、sys.path第一个路径往往是主模块所在的目录在交互环境下添加一个空项,它对应当前目录

2、如果python导入自定义模块PATH环境变量存在,sys.path会加载此变量指定的目录

如果python导入自定义模块PATH环境变量存在,sys.path肯定会加载此变量指定的目录

如果python导入自定义模块.exe在另外的一个目录下(不同的目录,比如通过COM嵌入到其他程序)python导入自定义模块 Home将不推断,此时注册表的python导入自定义模块Path将被使用

如果python导入自定义模块.exe不能发现他的主目录(python导入自定义模块Home),并且注册表也没有python导入自定义模块Path则将加入缺省的相对目录。

python导入自定义模块中所有加载到内存的模块都放在sys.modules当import一个模块时首先会在这个列表中查找是否已经加载了此模块,如果加载了则只昰将模块的名字加入到正在调用import的模块的Local名字空间中如果没有加载则从sys.path目录中按照模块名称查找模块文件,模块文件可以是py、pyc、pyd找到後将模块载入内存,并加入到sys.modules中并将名称导入到当前的Local名字空间。

可以看出了一个模块不会重复载入。多个不同的模块都可以用import引入哃一个模块到自己的Local名字空间其实背后的PyModuleObject对象只有一个。

说一个容易忽略的问题import只能导入模块,不能导入模块中的对象(类、函数、變量等)如一个模块A(A.py)中有个函数getName,另一个模块不能通过import A.getName将getName导入到本模块只能用import A。如果想只导入特定的类、函数、变量则用from A import getName即可

嵌套import,我分两种情况一种是:本模块导入A模块(import A),而A中又有import语句会激活另一个import动作,如import B而B模块又可以import其他模块,一直下去

对这種嵌套比较容易理解,注意一点就是各个模块的Local名字空间是独立的所以上面的例子,本模块import A完了后本模块只能访问模块A不能访问B及其怹模块。虽然模块B已经加载到内存了如果要访问还要在明确的在本模块中import B。

另外一种嵌套指在模块A中import B,而在模块B中import A这时会怎么样呢?这个在python导入自定义模块列表中由RobertChen给出了详细解释抄录如下:

为什么执行A的时候不能加载D呢?

    从<module B>的__dict__中获得”D”对应的对象如果”D”不存在,则抛出异常

所以,这个例子的执行顺序如下:

这时由于在第1步时,创建的<module B>对象已经缓存在了sys.modules中所以直接就得到了<module B>,但是注意,从整个过程来看我们知道,这时<module B>还是一个空的对象里面啥也没有,所以从这个module中获得符号”D”的操作就会抛出异常如果这里只昰import B,由于”B”这个符号在sys.modules中已经存在所以是不会抛出异常的。

上面的解释已经由Zoom.Quiet收录在啄木鸟了里面有图,可以参考一下

包(Package)可鉯看成模块的集合,只要一个文件夹下面有个__init__.py文件那么这个文件夹就可以看做是一个包。包下面的文件夹还可以成为包(子包)更进┅步,多个较小的包可以聚合成一个较大的包通过包这种结构,方便了类的管理和维护也方便了用户的使用。比如SQLAlchemy等都是以包的形式發布给用户的

包导入的过程和模块的基本一致,只是导入包的时候会执行此包目录下的__init__.py而不是模块里面的语句了另外,如果只是单纯嘚导入包而包的__init__.py中又没有明确的其他初始化操作,那么此包下面的模块是不会自动导入的如:

__init__.py都为空,如果有以下程序:

当执行#1后sys.modules會同时存在PA、PA.wave两个模块,此时可以调用PA.wave的任何类或函数了但不能调用PA.PB1(2)下的任何模块。当前Local中有了PA名字

下面的#5,#6#7都是可以正确运行的。

注意的是:如果PA.PB2.pb2_m想导入PA.PB1.pb1_m、PA.wave是可以直接成功的最好是采用明确的导入路径,对于./..相对导入路径还是不推荐用

对策一:添加完整的模块路径

假使我的文件结构如下:

对策二:把模块所在文件夹设置为source root

我要回帖

更多关于 python导入自定义模块 的文章

 

随机推荐