__main__ 模块: 我们知道一个有效的.py文件可以作为模块导入,然后被其他的python程序使用其中的类,函数等,这时候这个模块的名字和文件的名字相同;除了可以被import,这个.py文件也可以直接运行,它运行的时候,可能还导入了许多其他的module, 那么这时候从module的角度来看这个包含了很多个模块的运行着的对象,应该叫做什么模块呢? 答案是 : __main__ 模块, 所以__main__ 模块代表着一个运行着的对象。当我们看到 : from __main__ import __requires__ 这个语句的时候,我们知道 :需要在这个运行的对象里面定义一个 __requires__ 变量,因为这个运行的对象可能包含了很多个.py文件,所以可以在其中任意一个文件里面对这个变量赋值,只要赋值是在引用之前就可以了
pkg_resources 模块: 模块导入的时候,都存在一个初始化的过程,对于这个模块来说,初始化所做的事情包含“创建workingset”, 顾名思义,set 通常指集合,这里也可以这么理解,所以这个所谓的workingset 就是从资源中收集各种信息,包括依赖关系,程序入口等各种信息,收集之后,用户就可以通过pkg_resources模块访问这些资源,那么到底从哪个资源中收集这些信息呢? pkg_resources 只是从资源中收集信息,需要用户通过 __requires__这个参数来指定具体的资源,所以在使用 pkg_resources模块的时候,都需要首先定义变量 __requires__ 的值,这个变量 __requires__的值不需要是一个 文件的路径,因为 pkg_resources 模块本身会根据用户提供的信息"拼接"出资源的路径,然后在sys.path中查找这个资源,如果找不到,那么就会报错;如果找到,那么还会加载其依赖的相关包等(如果没有加载的话) ,最后完成 workingset的创建,也就是资源收集工作;如果用户没有指定 __requires__这个变量的值,那么就在当前的环境下进行workingset的收集,这样使用pkg_resources的意义就不大. 所以 pkg_resources 总是和 __requires__ 一起使用. 在pkg_resources这个模块的帮助文档中,描述了该模块支持的几种资源,其中一种是.egg资源,这种资源是pytho早期发布项目时候使用的一种格式,类似java项目发布时候使用.jar 格式. 如果pkg_resources找到的资源是 .egg格式的,那么需要了解.egg资源的文件目录结构,然后才可以更好的理解 pkg_resources.run_script等调用. 在pkg_resources 成功导入之后,就已经成功的创建了相应的workingset, 然后最常使用的就是其 run_script 或者 load_entry_point 等,这些方法用于 调用程序的真正入口,不同version的pkg_resources,对应的方法可能不完全相同;比如下面的代码,其通过 pkg_resources的run_script调用 ansible脚本,从而提供了ansible的命令:
代码语言:javascript复制 #!/bin/python
__requires__ = 'ansible==1.7.2'
__import__('pkg_resources').run_script('ansible==1.7.2', 'ansible')