通过epydoc为python包生成api信息
epyparse的Python项目详细描述
epydoc解析的python源代码的格式化和序列化。 源代码只进行文本解析,从不导入。
命令行用法
预打印
pretty打印命名对象或文件的api表示:
$ epyparse print -path <name_or_path> [options]
可缩短为:
$ epyparse <name_or_path> [options]
默认情况下,终端的输出是彩色的,您可以使用 -nocolor选项。
序列化
将命名对象或文件的递归api结构展平为序列 个人字典。每个字典都被json序列化并保存到 它自己的文件:
$ epyparse serialize -path <name_or_path> [options]
默认情况下,文件会写入当前工作目录,您可以 使用-out选项指定另一个目录:
$ epyparse serialize -path <name_or_path> -out docs/api
编程用法
顶级函数是解析的,展平的,pprint和对象化的:
>>> from epyparse import parsed, flattened, pprint, objectify
输入可以是文件路径:
>>> pprint('setup.py') ################################################################################ # setup ################################################################################ """ """ <BLANKLINE> import distutils.core.setup import sys import os import epyparse <BLANKLINE>
必须存在:
>>> parsed('does/not/exist') Traceback (most recent call last): ... IOError: No such file does/not/exist
或命名对象:
>>> pprint('os.getenv') def getenv(key, default=None): """ Get an environment variable, return None if it doesn't exist. The optional second argument can specify an alternate default. """ <BLANKLINE>
必须可以访问:
>>> pprint('does.not.exist') Traceback (most recent call last): ... ImportError: No Python source file found.
而不是内置或基于c的对象:
>>> pprint('cStringIO.StringIO') Traceback (most recent call last): ... ImportError: No Python source file for builtin modules.
可以访问模块、函数、类或方法:
>>> pprint('StringIO.StringIO.write') def write(self, s): """ Write a string to the file. <BLANKLINE> There is no return value. """ <BLANKLINE>
解析到嵌套字典
解析模块:
>>> d = parsed('epydoc.apidoc') >>> sorted(d.keys()) ['children', 'docstring', 'fullname', 'imports', 'type'] >>> d['type'] 'module' >>> for item in sorted(d['children'], key=lambda d: (d['type'], d['fullname'])): ... print item['type'], ' -> ', item['fullname'] class -> epydoc.apidoc.APIDoc class -> epydoc.apidoc.ClassDoc class -> epydoc.apidoc.ClassMethodDoc class -> epydoc.apidoc.DocIndex class -> epydoc.apidoc.DottedName class -> epydoc.apidoc.GenericValueDoc class -> epydoc.apidoc.ModuleDoc class -> epydoc.apidoc.NamespaceDoc class -> epydoc.apidoc.PropertyDoc class -> epydoc.apidoc.RoutineDoc class -> epydoc.apidoc.StaticMethodDoc class -> epydoc.apidoc.ValueDoc class -> epydoc.apidoc.VariableDoc class -> epydoc.apidoc._Sentinel function -> epydoc.apidoc._flatten function -> epydoc.apidoc._pp_apidoc function -> epydoc.apidoc._pp_dict function -> epydoc.apidoc._pp_list function -> epydoc.apidoc._pp_val function -> epydoc.apidoc.pp_apidoc function -> epydoc.apidoc.reachable_valdocs
扁平化和json序列化
对于对象。get_parent和对象。get_children反序列化 方法,我们依赖于 保存到与文件名和规范名相同的目录中 没有文件扩展名:
>>> import os, json >>> assert not os.path.exists('TESTOUT') >>> os.mkdir('TESTOUT') >>> for item in flattened('epydoc.apidoc'): ... print item['fullname'] ... with open('TESTOUT/' + item['fullname'], 'w+b') as fp: ... json.dump(item, fp) ... epydoc.apidoc._flatten epydoc.apidoc._pp_apidoc epydoc.apidoc._pp_dict epydoc.apidoc._pp_list epydoc.apidoc._pp_val epydoc.apidoc.pp_apidoc epydoc.apidoc.reachable_valdocs epydoc.apidoc.APIDoc.__cmp__ epydoc.apidoc.APIDoc.__hash__ epydoc.apidoc.APIDoc.__init__ epydoc.apidoc.APIDoc.__repr__ epydoc.apidoc.APIDoc._debug_setattr epydoc.apidoc.APIDoc._debug_setattr epydoc.apidoc.APIDoc.apidoc_links epydoc.apidoc.APIDoc.is_detailed epydoc.apidoc.APIDoc.merge_and_overwrite epydoc.apidoc.APIDoc.pp epydoc.apidoc.APIDoc.pp epydoc.apidoc.APIDoc.specialize_to epydoc.apidoc.APIDoc epydoc.apidoc.ClassDoc._c3_merge epydoc.apidoc.ClassDoc._c3_mro epydoc.apidoc.ClassDoc._dfs_bases epydoc.apidoc.ClassDoc._report_bad_base epydoc.apidoc.ClassDoc.apidoc_links epydoc.apidoc.ClassDoc.is_exception epydoc.apidoc.ClassDoc.is_newstyle_class epydoc.apidoc.ClassDoc.is_type epydoc.apidoc.ClassDoc.mro epydoc.apidoc.ClassDoc.select_variables epydoc.apidoc.ClassDoc epydoc.apidoc.ClassMethodDoc epydoc.apidoc.DocIndex.__init__ epydoc.apidoc.DocIndex._get epydoc.apidoc.DocIndex._get_from epydoc.apidoc.DocIndex._get_module_classes epydoc.apidoc.DocIndex._update_funcid_to_doc epydoc.apidoc.DocIndex.container epydoc.apidoc.DocIndex.find epydoc.apidoc.DocIndex.get_valdoc epydoc.apidoc.DocIndex.get_vardoc epydoc.apidoc.DocIndex.reachable_valdocs epydoc.apidoc.DocIndex.read_profiling_info epydoc.apidoc.DocIndex epydoc.apidoc.DottedName.InvalidDottedName epydoc.apidoc.DottedName.__add__ epydoc.apidoc.DottedName.__cmp__ epydoc.apidoc.DottedName.__getitem__ epydoc.apidoc.DottedName.__hash__ epydoc.apidoc.DottedName.__init__ epydoc.apidoc.DottedName.__len__ epydoc.apidoc.DottedName.__radd__ epydoc.apidoc.DottedName.__repr__ epydoc.apidoc.DottedName.__str__ epydoc.apidoc.DottedName.container epydoc.apidoc.DottedName.contextualize epydoc.apidoc.DottedName.dominates epydoc.apidoc.DottedName epydoc.apidoc.GenericValueDoc.is_detailed epydoc.apidoc.GenericValueDoc epydoc.apidoc.ModuleDoc.apidoc_links epydoc.apidoc.ModuleDoc.init_submodule_groups epydoc.apidoc.ModuleDoc.select_variables epydoc.apidoc.ModuleDoc epydoc.apidoc.NamespaceDoc.__init__ epydoc.apidoc.NamespaceDoc._init_grouping epydoc.apidoc.NamespaceDoc.apidoc_links epydoc.apidoc.NamespaceDoc.group_names epydoc.apidoc.NamespaceDoc.init_sorted_variables epydoc.apidoc.NamespaceDoc.init_variable_groups epydoc.apidoc.NamespaceDoc.is_detailed epydoc.apidoc.NamespaceDoc.report_unused_groups epydoc.apidoc.NamespaceDoc epydoc.apidoc.PropertyDoc.apidoc_links epydoc.apidoc.PropertyDoc.is_detailed epydoc.apidoc.PropertyDoc epydoc.apidoc.RoutineDoc.all_args epydoc.apidoc.RoutineDoc.is_detailed epydoc.apidoc.RoutineDoc epydoc.apidoc.StaticMethodDoc epydoc.apidoc.ValueDoc.__getstate__ epydoc.apidoc.ValueDoc.__repr__ epydoc.apidoc.ValueDoc.__setstate__ epydoc.apidoc.ValueDoc.apidoc_links epydoc.apidoc.ValueDoc.pyval_repr epydoc.apidoc.ValueDoc.summary_pyval_repr epydoc.apidoc.ValueDoc epydoc.apidoc.VariableDoc.__init__ epydoc.apidoc.VariableDoc.__repr__ epydoc.apidoc.VariableDoc._get_defining_module epydoc.apidoc.VariableDoc.apidoc_links epydoc.apidoc.VariableDoc.is_detailed epydoc.apidoc.VariableDoc epydoc.apidoc._Sentinel.__init__ epydoc.apidoc._Sentinel.__nonzero__ epydoc.apidoc._Sentinel.__repr__ epydoc.apidoc._Sentinel epydoc.apidoc
反序列化为对象
>>> from epyparse import objectify
>>> obj = objectify('TESTOUT/epydoc.apidoc.APIDoc.merge_and_overwrite')
返回的对象类型是dict子类:
>>> sorted(obj.keys()) [u'args', u'attributes', u'fullname', u'is_method', u'lineno', u'params', 'src', u'type']
具有属性样式访问:
>>> obj.args [u'self', u'other'] >>> obj.is_method True >>> obj.lineno * 0 0 >>> obj.params [[u'ignore_hash_conflict', False]] >>> obj.name u'merge_and_overwrite'
object.parent提供父对象的名称(如果有):
>>> obj.parent u'epydoc.apidoc.APIDoc'
而且,因为我们已经将父目录序列化到同一个目录,所以我们可以 使用对象检索它。get_parent方法:
>>> parent = obj.get_parent() >>> parent.fullname u'epydoc.apidoc.APIDoc' >>> parent.type u'class' >>> parent.name u'APIDoc'
类似地,object.members返回对象成员的名称(如果有):
>>> for name in sorted(parent.members): ... print parent.fullname + '.' + name epydoc.apidoc.APIDoc.__cmp__ epydoc.apidoc.APIDoc.__hash__ epydoc.apidoc.APIDoc.__init__ epydoc.apidoc.APIDoc.__repr__ epydoc.apidoc.APIDoc._debug_setattr epydoc.apidoc.APIDoc._debug_setattr epydoc.apidoc.APIDoc.apidoc_links epydoc.apidoc.APIDoc.is_detailed epydoc.apidoc.APIDoc.merge_and_overwrite epydoc.apidoc.APIDoc.pp epydoc.apidoc.APIDoc.pp epydoc.apidoc.APIDoc.specialize_to
和对象。获取成员反序列化每个成员:
>>> for child in sorted(parent.get_members(), key=lambda d: d['fullname']): ... print child.type, ' -> ', child.name function -> __cmp__ function -> __hash__ function -> __init__ function -> __repr__ alias -> _debug_setattr alias -> _debug_setattr function -> apidoc_links function -> is_detailed function -> merge_and_overwrite function -> pp function -> pp function -> specialize_to
反省-检查vs.检查
>>> import inspect >>> from epydoc.apidoc import APIDoc >>> from epyparse import Inspector >>> merge_and_overwrite_obj = obj >>> APIDoc_obj = parent
argspec(不完全相同,但足以显示函数签名):
>>> inspect.getargspec(APIDoc.merge_and_overwrite) ArgSpec(args=['self', 'other', 'ignore_hash_conflict'], varargs=None, keywords=None, defaults=(False,)) >>> Inspector.getargspec(merge_and_overwrite_obj) ArgSpec(args=[u'self', u'other', u'ignore_hash_conflict'], varargs=None, keywords=None, defaults=(False,)) >>> inspect.getargspec(APIDoc.apidoc_links) ArgSpec(args=['self'], varargs=None, keywords='filters', defaults=None) >>> Inspector.getargspec(APIDoc_obj.get_member('apidoc_links')) ArgSpec(args=[u'self'], varargs=None, keywords=u'filters', defaults=None)
哈萨特:
>>> hasattr(APIDoc, 'merge_and_overwrite') True >>> Inspector.hasattr(APIDoc_obj, 'merge_and_overwrite') True >>> Inspector.hasattr(APIDoc_obj, 'somethingsomethingorangessomething') False
目录
>>> dir(merge_and_overwrite_obj) ['__dict__', u'__doc__', u'__name__'] >>> sorted(dir(APIDoc_obj))[:7] [u'__cmp__', '__dict__', u'__doc__', u'__hash__', u'__init__', u'__name__', u'__repr__'] >>> sorted(dir(APIDoc_obj))[7:13] [u'_debug_setattr', u'_debug_setattr', u'apidoc_links', u'is_detailed', u'merge_and_overwrite', u'pp'] >>> module_obj = objectify('TESTOUT/epydoc.apidoc') >>> sorted(dir(module_obj))[:7] [u'APIDoc', u'ClassDoc', u'ClassMethodDoc', u'DocIndex', u'DottedName', u'GenericValueDoc', u'ModuleDoc']
_医生
>>> hasattr(APIDoc.merge_and_overwrite, '__doc__') True >>> hasattr(merge_and_overwrite_obj, '__doc__') True >>> Inspector.hasattr(merge_and_overwrite_obj, '__doc__') True >>> actual = ''.join( ... s.strip() for s in APIDoc.merge_and_overwrite.__doc__.splitlines() if s.strip() ... ) ... >>> serialized = ''.join( ... s.strip() for s in merge_and_overwrite_obj.__doc__.splitlines() if s.strip() ... ) ... >>> assert len(actual) and len(serialized) >>> assert actual == serialized
_听写
>>> Inspector.hasattr(merge_and_overwrite_obj, '__dict__') True >>> d = Inspector.getattr(merge_and_overwrite_obj, '__dict__') >>> d['__name__'] u'merge_and_overwrite' >>> print d['__doc__'] #doctest: +ELLIPSIS Combine C{self} and C{other} into a X{merged object}, such that any changes made to one will affect the other. Any...
基类
整理:
>>> import shutil >>> shutil.rmtree('TESTOUT')