”ImportError: No module named t2“---python的import机制+模块的搜索路径

一、背景

       最近在学pyhonweb框架Karrigell,下载了源码之后运行,出现了error:

                                   ImportError:No module named k_target

       在www/index.py里面importk_target,但是运行的时候出现了上述错误,网上查了一下,知道

       是不同目录下 import模块或者包的话,需要将模块或者包的路径加入到sys.path中。于是使用了

       sys.path.append('e:\Karrigell\karrigell\core')解决了问题。借此机会又重新学习了一下python

       import机制和搜索路径。

二、python的import机制

2.1 模块和包

      模块化编程使得软件开发更加灵活,不同的功能可多人协作完成,同时便于代码复用和后期维护,

      python使用import模块/包来组织各个模块,使不同模块直接可以调用。

     模块:python中,每个py文件被称之为模块,它可以定义变量,方法和类;

     包:是一个目录,它可以包含py文件和子目录,最重要的一点是包一定含有一个__init__.py文件。

      只要模块或者包所在的目录在sys.path中,就能使用import 来引用其他模块内的变量,方法和类。

 2.2 import的过程

    1. Python中所有加载到内存的模块都放在sys.modules。当import一个模块时首先会在这个列表中

        查找是否已经加载了此模块,如果加载了则只是将模块的名字加入到正在调用import的模块的

        Local名字空间中。如果没有加载则从sys.path目录中按照模块名称查找模块文件,模块文件可以

       是pypycpyd找到后将模块载入内存,并加入到sys.modules中,并将名称导入到当前的

       Local名字空间。若没有找到,则import没有效果,运行时出现ImportError:Nomodule named ***.

       所以:                                             import A

                                                                    |

                                                   查看sys.moudles--->找到,导入模块名字到当前模块

                                                                    |

                                  没有找到,则搜索sys.path--->找到,模块加载到内存,加入sys.moudles

                                                                   |

                                             没有找到,则import没有效果

 

    2.每个模块在内存只有一份,即pyModuleObject对象只有一个,首次import该模块时加载到内存,

        然后存放在sys.modules里,其他模块再引用该模块的时候,在sys.modules里面可以直接找到。

 2.3  包的import

       前面已经讲了只要有__init__.py,这个目录都可以称为一个包。包下面的子目录也可以是子包。

       如果查看包的类型importSQLAlchemy type(SQLAlchemy),可以看到其实也是<type'module'>

      所以import包的时候,查找路径也是sys.path,加载到内存后也会放在sys.modules中。

       import包的时候,需要考虑__init__.py,因为首次导入包的时候会执行此文件里面的语句而不是

      模块里面的语句,例如执行importpackage;就会执行__init__.py文件,如果想在导入包时做一些

      初始化工作,eg:导入其他的包都可以写在这个文件里面。eg:列表__all__=["module1","module2"],

      它包含了执行 from package  import  *时导入的模块。

 2.4 import的使用

      如果想要引用某个模块A.py中内容,有两种方法:

       1.import A; A.func()这实际上是把整个A的代码在当前环境中执行了一遍,A模块里面的变量,

         方法都可以被当前模块引用

       2.from A import funcfunc();这个是在当前环境中建立和变量func()同名的对象,并且将A中的

          变量赋值给它,直接引用变量或者方法,但是你不能在当前模块里面定义同名的变量或者函数。

       注意:import只能模块,包,而不能直接import变量,函数,类。importA.func()就是错的。

      如果想要引用某个包B,也有几种方法:

       1.import B; 想要使用B包下面A模块的func,B.A.func()-----这时,一定要在__init__里进行一些

         初始化设定,否则内存中只加载了B,并没有加载模块Afunc()调用不到

      2.import B.A ; B.A.func()

      3.from B import A; A.func() from B import *,可以引用所有的模块

      4.from B.A import func; func()

      5.from B import A as a1;A取了别名

 2.5  import的嵌套

     1. A模块importB, B模块importCA中建立了一个local的名字空间BA模块只能访问B中的变量

        和函数,而不能访问C的。如果想访问C,只能importC

     2. A模块importBB模块importA.参考:http://blog.csdn.net/sinat_16790541/article/details/43376741

三、模块的搜索路径

      由前面我们知道import模块的时候,如果模块没有在sys.modules里面,即没有加载进内存,

      那么会去sys.path里面搜索模块,这里sys.path就是模块的搜索路径,如果看一个模块能不能

      import成功,就看它是否在sys.path里面可以找到。

      1. sys.path的第一个选项,是主模块所以目录,在交互环境下是一个空项,对应当前目录。

      2.windows下,若设置了PYTHONPATH,那么这里设定的路径会被自动添加到sys.path里面,

        所以可以自己添加PYTHONPATH

      3.将自己想要import的模块或者包的路径添加到sys.path里,sys.path.append("路径名”)

          -------但是这是暂时性的,只要重新运行python,这个路径就消失了

      4.将自己想要import的模块或者包放到site_packages目录下.

        (from distutils.sysconfig import get_python_lib; printget_python_lib()site-packages目录)

      5.使用pth文件,在site-packages文件中创建.pth文件,将模块的路径写进去,一行一个路径

      6.将自己想要import的模块添加到$python_dir/lib


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值