1.概述
在上一篇main.py学习中我们提到main.py涉及三种重要的数据结构,本篇针对其中的一种:all_commands对象列表展开分析。all_commands列表来自于repo工程中的subcmds这个模块包,通过python包导入机制启动__init__.py来遍历subcmds包中所有cmd.py,并将其中定义的cmd类生成对象保存到列表中,供main.py中调用。
2.数据结构
all_commands是一个列表,其中每一个元素都是一个对象,对象对应于以某个repo子命令首字母大写命名的类,这些类均继承于Commands类并各自重写了Execute、_Options等方法用于差异化地执行各种repo子命令的功能。
3.主体思路
前提:python模块包在import时会自动执行__init__.py。
文件结构:subcmds模块包中每一个py文件都对应一个repo子命令并以子命令名称命名,在每个py文件中会定义repo子命令的对应类(从command类继承)。
我们来看__init__.py的思路:
通过__file__获取当前路径开始遍历所有文件 -->
对以.py结尾的非__init__.py的文件获取其名称name和首字母大写后的name即clsn -->
code: if py.endswith('.py'):
name = py[:-3]
clsn = name.capitalize()
使用内建函数__import__动态导入subcmds路径下名称为name的submodule -->
code: mod = __import__(__name__, globals(), locals(), ['%s' % name])
使用内建函数getattr获取mod的名为name的module的名为clsn的类并创建对象cmd -->
code: mod = getattr(mod, name) cmd = getattr(mod, clsn)()
更新cmd的NAME属性并将cmd放入列表中
code: cmd.NAME = name all[name] = cmd
4.算法思路
repo对于subcmds模块包的使用方式值得借鉴,将不同场景的处理模式封装成类,并在导入模块包时实例化这些类的对象最后以列表的形式对外提供使用。
附内建函数__import__:
Python 提供内建函数 __import__ 动态加载 module,__import__ 的用法如下: