一、模块
在python中,模块就是python文件,其后缀为.py。我们通过import语句来导入模块或者导入模块中的类、函数。
比如,我们创建了一个名为database的模块,在dababase中定义了一个Database类。如果想要导入这个类,有以下几种方法:
- 导入模块
import database
db = database.Database()
- 直接导入类
from database import Database
db = Database()
如果当前模块中已经有一个名为Database的对象,或者觉得Database写起来太长了,也可以导入之后重命名.
from database import Database as DB
db = DB()
- 一次导入多个条目
如果database中还有一个Query类,也可以同时导入两个类
from database import Database, Query
- 全部导入
也有人觉得逐个导入很麻烦,所以选择一次性全部导入
from database import *
一定不要这样做!!!
这样做会导致你找不到当前使用的类是哪里来的;另一方面,全部导入会污染命名空间,把你不需要的类也一并导入进来。
二、包
一个包就是一个目录下所有模块的集合,包的名字就是目录的名字。我们需要在目录下创建一个名为init.py的文件,来告诉python这个目录是一个包。通常情况下,这个文件中什么都不需要写。
现在,我们的工作目录如下:
project
--main.py
--ecommerce/
----__init__.py
----database.py
----products.py
----payments/
------__init__.py
------square.py
------stripe.py
----contacts/
------email.py
导入方法有两种,分别是,绝对导入以及相对导入。
- 绝对导入
绝对导入是指定我们要导入的模块、函数的完整路径。比如,我们想要访问products.py中的Product类,可以用:
import ecommerce.products
product = ecommerce.products.Product()
或者
from ecommerce.products import Product
product = Product()
这些语句在main.py或者其他文件中都可以使用。
- 相对导入
如果想要在products模块中使用database中的Database类,也可以用相对导入的方法:
from .database import Dababase
这里,.意思是“在当前包内搜索”,在这里也就是ecommerce包。
如果想要在database模块中访问email模块,就需要用两个点号,表示payment包的上一层。
from ..contact.email import send_mail
如果不想写上面那么长的路径,也可以通过修改__init__.py来导入。比如,我们在ecommerce/__init__.py中写入:
from .database import db
就可以在main.py中直接访问db属性
from ecommerce import db
如果我们将一个模块的所有代码拆成好几个文件,组织在一个包里,就可以在包的__init__.py中把这些属性到导入,这样之后就可以通过从包里导入属性就可以了。
三、组织模块
按照上面的例子,如果我们在products.py中直接导入database模块,然后运行products.py脚本,就会报错:
很奇怪,哪里来的__main__? 这是因为,每个模块都有一个变量__name__,当我们将这个模块作为运行脚本时,它的__name__就会被赋值为__main__,按照__main__.database去搜索database,自然是找不到的;否则,如果我们将这个模块导入,它的__name__就是它的模块名,比如ecommerce.product,此时,按照ecommerce.database去搜索database模块,就没有问题了。
我们将一个模块进行导入时,可能有些代码是不希望被一并导入的,因为一旦导入,就会立即被执行,而这些代码我们只希望将这个脚本作为执行脚本时,才会被执行。此时,就出现了一个我们在python代码中经常见到的操作:
# 将启动代码放在main()中
if __name__ == '__main__':
main()
这样,只有当这个脚本被执行,才会运行main函数中的代码,否则,单纯是被导入时,不会执行。
网友评论