整合在一起
一旦对象被导入,我们可以开始检测了。这是一个简单的例子,重复调用 getmembers(object, filter),过滤器是一个有用的 is 函数。你能够发现 isclass 和 isfunction,其它相关的方法都是 is开头的,例如,ismethod,isgenerator,iscoroutine。这都取决于你是否想写一些通用的,可以处理所有的特殊情况,或一些更小的和更特殊的源代码。我坚持前两点,因为我不用把采用3个不同方法来创建我想要的格式化模块,类和功能。def getmarkdown(module):
output = [ module_header ]
output.extend(getfunctions(module)
output.append("***\n")
output.extend(getclasses(module))
return "".join(output)def getclasses(item):
output = list() for cl in inspect.getmembers(item, inspect.isclass): if cl[0] != "__class__" and not cl[0].startswith("_"): # Consider anything that starts with _ private
# and don't document it
output.append( class_header )
output.append(cl[0])
# Get the docstring
output.append(inspect.getdoc(cl[1]) # Get the functions
output.extend(getfunctions(cl[1])) # Recurse into any subclasses
output.extend(getclasses(cl[1]) return outputdef getfunctions(item): for func in inspect.getmembers(item, inspect.isfunction):
output.append( function_header )
output.append(func[0]) # Get the signature
output.append("\n```python\n)
output.append(func[0])
output.append(str(inspect.signature(func[1]))
# Get the docstring
output.append(inspect.getdoc(func[1])
return output
当要格式化大文本和一些编程代码的混合体时,我倾向于把它作为一个在列表或元组中的独立项目,用 "".join() 来合并输出。在写作的时候,这种方法其实比基于插值的方法(.format 和 %)更快。然而,python 3.6 的新字符串格式化将比这更快,更具可读性。
你可以看到,getmembers() 返回一个元组与对象的名称在第一位置和第二位置的实际对象,我们可以用递归遍历对象层次。
对于检索到的每一个项目,可能使用 getdoc() 或 getcomments() 获取文档字符串和注释。对于每一个功能,我们可以使用 signature() 得到 Signature 对象 ,它表示其位置参数和关键字参数的默认值和任何注释,为我们提供了产生简单直接的描述和良好风格的文本,有助于我们理解用户我们写代码的意图。