模块和包

一、import 模块

import一个模块相当于执行了这个模块,导入模块后可以使用模块中的属性和方法,比如模块名.变量、模块名.函数

当前模块和被导入模块是存在两个不同的内存空间

import模块的原理:

① 寻找模块

② 找到模块就开辟一块空间,来执行这个模块

③ 把这个模块中用到的名字都收录到新开辟的空间中

④ 创建一个变量来引用这个模块的空间

导入模块注意点:

① 一个模块不能被重复导入
② 模块和模块之间的内存空间始终是隔离的

③ 模块的名字必须符合变量的命名规则,否则无法导入

④ 被导入模块的方法只会找到它自己的模块空间的属性

⑤ 一行只能导入一个模块(符合PEP8规范)

可以给导入的模块起别名,但起了别名以后,原来的模块名就不能使用了。

起别名的原理:找到这个模块,用别名指向它,所以原模块名跟模块没关系了

import XXX as X

# mymodule.py
a = 1

def func():
    print(222)

# main.py
import mymodule as m
print(m.a)
m.func()

模块的搜索路径:

执行一个文件,依靠的是sys.path

pycharm会将项目的目录放进去,但是运行程序有时并不在pycham,

目前python会及那个当前文件的目录导进来,然后再导入项目

正常的sys.path中除了内置、扩展模块所在的路径之外

只有一个路径是永远不会出现问题,直接执行的这个文件所在的目录

一个模块能否被导入,就看这个模块所在的目录在不在sys.path中

两种运行py文件的方式:

① 直接运行:cmd下 python xxx.py 

 以脚本的形式去运行,__name__ == '__main__'

② 导入模块

__name__ == '模块名'

if __name__ == '__main__'

当一个文件作为一个脚本又作为一个模块,作为模块的时候将打印的东西放在 if __name__ == '__main__' 逻辑里

所有的打印逻辑和函数的调用,都放在  if __name__ == '__main__'  的逻辑内,一旦导入模块的时候,if的内容不会执行

二、from... import ...

① from 模块 import 变量/方法

找到模块,开辟空间执行模块

所有的模块里的属性和方法都存储的模块的所属的空间中

在全局命名空间创建一个变量名/方法名分别指向模块中的名字

# mymodule.py

a = 1

def func():
    print(222)

# main.py

from mymodule import a
print(a)

② from 模块 import *

相当于把模块的所有方法、变量导入到当前的全局命名空间中。

一般情况下,使用的变量超过5个就使用星号

在模块中添加了 __all__, 把模块里能用的变量或者方法放在__all__中,但all只能跟*配合使用

# mymodule.py

__all__ = ['a','b']         # 如果导入的是星号,只能使用a、b两个变量,不能使用方法
a = 1
b = 2

def func():
    print(222)

def func2():
    print(333)


# main.py

from mymodule import *      # 只能使用模块里__all__定义的内容
func()
print(a)

# 报错,NameError: name 'func' is not defined

三、模块的补充:

① pyc文件、pyi文件

pyi文件是跟py一样文件,只是后缀名不一样,里面也是python的代码

pyc是编译好的字节码文件,但一个模块当作模块执行的时候,会产生一个pyc文件,下次导入模块的时候,会直接使用pyc文件,假如在下次调用前模块修改过,那么才会再产生一个pyc文件

pyc文件提高程序的启动效率并不能提高程序的执行效率,pyc文件再启动的时候会产生,如果要提高启动效率,提前先执行python程序

② 模块的导入和修改

导入模块后,在执行程序中修改模块的内容,源程序不会使用修改后的值,就算重新导入模块也不会使用修改后的值

解决方法(不建议使用):

from importlib import reload

reload(模块名)

③ 模块的循环引用

A import B

B import A

循环引用会报错,在程序中不要发生循环引用的问题,只能是单向引用,不能成环。

④ dir(模块名)

dir(模块名) 获取模块的是所有方法和属性,用反射的方式来调用

四、包

python3中的Directory和package都带__init__.py的文件

含有一个__init__.py的文件夹就是一个包

python2中没有__init__.py文件就不能导入模块了,但是可以手动创建__init__.py,这样就变成了一个包

从包中导入模块:

imprt XXX.XXX.XXX

点的左边必须是一个包,终点必须是一个模块,精确到具体的模块

from ... import ...

一般情况:from 包 import 模块

导入包:

导入包的过程相当于执行了这个包的__init__.py文件

作为一个包,所有包内的文件的导入都要考虑sys.path的问题(相对导入了这个问题)

sys.path中的内容 永远是当前执行的文件

绝对路径导入优点:能看清楚目录的层次关系

绝对路径导入缺点:每次移动都要修改绝对导入路径

glance/                   

├── __init__.py      from glance import api
                             from glance import cmd
                             from glance import db

├── api                  

│   ├── __init__.py  from glance.api import policy
                              from glance.api import versions

│   ├── policy.py

│   └── versions.py

├── cmd                 from glance.cmd import manage

│   ├── __init__.py

│   └── manage.py

└── db                   from glance.db import models

    ├── __init__.py

    └── models.py
绝对导入

相对路径导入

. 表示当前目录

.. 表示上一层目录

glance/                   

├── __init__.py      from . import api  #.表示当前目录
                     from . import cmd
                     from . import db

├── api                  

│   ├── __init__.py  from . import policy
                     from . import versions

│   ├── policy.py

│   └── versions.py

├── cmd              from . import manage

│   ├── __init__.py

│   └── manage.py    from ..api import policy   
                     #..表示上一级目录,想再manage中使用policy中的方法就需要回到上一级glance目录往下找api包,从api导入policy

└── db               from . import models

    ├── __init__.py

    └── models.py

相对导入
相对导入

如果带着相对路径导入的文件,就不能被执行,只能是当作模块导入。

相对路径导入一般是给包外的文件提供服务,包内的文件不能执行,运用了相对路径导入的文件不能被执行。

五、项目目录规划

项目名称的文件夹

  bin 文件夹               (只能由start.py 文件,只有一个文件,而且名字不能改变)

    start.py     # 负责项目的启动

  conf  文件夹        (配置文件的目录,文件都要统一格式)

    config.ini

    settings.py(推荐使用)

  

  core 文件夹              (存放的是核心代码)

  db    文件夹               (存放的是数据文件,不是py文件)

  lib    文件夹    (存放库文件,放第三方模块或者自定义模块)

  log  文件夹     (存放的是log文件)   

    log

原文地址:https://www.cnblogs.com/st-st/p/9605550.html