我正在使用python 3.1。
是否可以为单个模块或函数创建多个文档字符串? 我正在创建一个程序,我打算有多个docstrings,每个都有一个类别。我打算给其他人这个程序,以便他们可以使用它,并为程序员和非程序员提供方便,我正在为程序本身的文档提供文档字符串。
更具体地说,我在程序/模块中有一个菜单作为接口,其中一个选项将允许访问模块docstring以获取程序文档。因此,如果可能的话,我想制作多个文档字符串来对不同类型的文档进行分类。因此,如果用户希望查看文档的某些部分,那么对用户来说会更容易。
例如。第一个docstring包含有关如何使用该程序的说明。第二个docstring包含有关程序的一部分如何工作的信息。第三个docstring包含有关另一部分如何工作的信息。等
这可能吗?如果是这样,你如何引用它们?
更新:添加评论。
我最初的想法实际上是在以下意义上有多个文档字符串:
def foo():
"""docstring1: blah blah blah"""
"""docstring2: blah blah blah"""
pass # Insert code here
然后会有一些代码可以让我引用这些文档字符串。 那么,我猜这是不可能的呢?
答案 0 :(得分:4)
我不建议尝试使用docstrings做一些复杂的事情。最好保持文档字符串简单,如果你想提供一堆不同的文档选项,还可以做其他事情。
如果你真的想做你所描述的,我建议你用标签分隔文档字符串中的部分。像这样:
def foo(bar, baz):
"""Function foo()
* Summary:
Function foo() handles all your foo-ish needs. You pass in a bar and a baz and it foos them.
* Developers:
When you change foo(), be sure you don't add any global variables, and don't forget to run the unit tests.
* Testers:
When you test foo, be sure to try negative values for baz.
"""
pass # code would go here
然后你可以很容易地将你的字符串拆分成块,当用户选择一个菜单项时,只显示相应的块。
s = foo.__doc__ # s now refers to the docstring
lst = s.split("\n* ")
section = [section for section in lst if section.startswith("Developers")][0]
print(section) # prints the "Developers" section
这样,当您在交互式Python shell中工作时,您可以说“help(foo)”,您将看到所有文档字符串。并且,您并没有改变Python基本部分的基本行为,这会让其他人试图研究您的代码。
您还可以做一些更简单的事情:只需为不同目的制作一个大型的全球文档字典,并从每个新事物的源代码中更新它。
doc_developers = {} doc_testers = {}
def foo(bar, baz):
"""Function foo()
Function foo() handles all your foo-ish needs. You pass in a bar and a baz and it foos them."
pass # code goes here
doc_developers["foo"] = "When you change foo(), be sure you don't add any global variables, and don't forget to run the unit tests."
doc_testers["foo"] = "When you change foo(), be sure you don't add any global variables, and don't forget to run the unit tests."
我最不喜欢的是,如果你改变函数foo的名称,你需要在多个地方更改它:一次在实际的def
中,一次在每个字典更新行中。但你可以通过写一个函数来解决这个问题:
def doc_dict = {} # this will be a dict of dicts
doc_dict["developers"] = {}
doc_dict["testers"] = {}
def doc_update(fn, d):
name = fn.__name__
for key, value in d.items():
doc_dict[key][name] = value
def foo(bar, baz):
"""Function foo()
Function foo() handles all your foo-ish needs. You pass in a bar and a baz and it foos them."
pass # code goes here
d = { "developers": "When you change foo(), be sure you don't add any global variables, and don't forget to run the unit tests.",
"testers": " When you test foo, be sure to try negative values for baz."}
doc_update(foo, d)
可能有办法将doc_update()变成装饰器,但我现在已经没时间了。
答案 1 :(得分:3)
你想考虑使用decorators干净地做什么~unutbu为函数提出建议:为每个函数添加一个单独的字段。例如:
def human_desc(description):
def add_field(function):
function.human_desc = description
return function
return add_field
这就是行动human_desc
的样子:
@human_desc('This function eggfoobars its spam.')
def eggfoobar(spam):
"Apply egg, foo and bar to our spam metaclass object stuff."
print spam
释
作为the doc explains,该位代码等同于以下内容:
def eggfoobar(spam):
"Apply egg, foo and bar to our spam metaclass object stuff."
print spam
eggfoobar = human_desc('This function eggfoobars its spam.')(eggfoobar)
和human_desc('This function eggfoobars its spam.')
返回以下函数:
def add_field(function):
function.human_desc = 'This function eggfoobars its spam.'
return function
正如您所看到的,human_desc
是一个函数,它为description
的值生成上面的装饰器,并将其作为参数传递。装饰器本身是一个接受要装饰(修改)的函数并返回它修饰的函数(在这种情况下,即添加那些额外的元数据)。简而言之,这相当于:
def eggfoobar(spam):
"Apply egg, foo and bar to our spam metaclass object stuff."
print spam
eggfoobar.human_desc = 'This function eggfoobars its spam.'
然而,语法更清晰,更不容易出错。
显然,无论哪种方式,你得到的是:
>>> print eggfoobar.human_desc
This function eggfoobars its spam.
答案 2 :(得分:2)
您可以使用定义了usage
和extra
属性的类,而不是使用函数。例如,
class Foo(object):
'''Here is the function's official docstring'''
usage='All about the usage'
extra='How another part works'
def __call__(self):
# Put the foo function code here
pass
foo=Foo()
你会像往常一样打电话:foo()
,
你可以获得正式的文档字符串,以及这样的备用文档字符串:
print foo.__doc__
print foo.usage
print foo.extra
您还可以将附加属性附加到普通函数(而不是像上面那样使用类),但我认为语法有点丑陋:
def foo():
pass
foo.usage='Usage string'
foo.extra='Extra string'
而且,模块也是对象。他们可以轻松拥有额外的属性:
如果定义模块常量
USAGE='''blah blah'''
EXTRA='''meow'''
然后导入模块时:
import mymodule
您可以使用
访问官方和备用文档字符串mymodule.__doc__
mymodule.USAGE
mymodule.EXTRA
答案 3 :(得分:0)
如果您想拥有多个可能的文档字符串,可以替换__doc__
属性,但请考虑使初始文档字符串足够灵活适用于所有类型。
答案 4 :(得分:0)
模块是类/函数/模块的集合。所以它的docstring给出了它包含的内容的介绍。
类docstring告诉类是什么,它的方法docstrings告诉我们这些方法是什么。一个类有一个目的,一个方法只做一个事情,所以它们应该有单个文档字符串。
函数做一件事,所以一个doctring就足够了。
我看不出多个docstrings的目的是什么。也许你的模块很大。分为子模块和文档字符串中的模块提及子模块。