【问题标题】:Python cmd dynamic docstrings for do_help() functiondo_help() 函数的 Python cmd 动态文档字符串
【发布时间】:2012-04-02 09:32:52
【问题描述】:

我正在开发一个 Pythonic 命令行“抽认卡”应用程序,以帮助用户学习不同的语言。我想使用 Python 的 cmd 库来加速开发——特别感兴趣的是 cmd.Cmd 类的 do_help() 方法,它打印出类的用户方法的文档字符串。但是,由于此应用程序的多语言特性,我希望能够放入特定语言的文档字符串。

我阅读了 this SO question 关于使用装饰器的信息,但我对装饰器知之甚少,我想知道它们是否适合我的特定困境,然后再投入大量时间学习它们。

你们怎么看?处理这种情况的最佳方法是什么?

如果您想了解有关我的问题的更多信息,请告诉我。

【问题讨论】:

    标签: python decorator docstring python-cmd


    【解决方案1】:

    装饰者将能够做你想做的事,除此之外。

    装饰底漆

    作为额外的奖励,装饰器在各种情况下都是非常有用的工具。他们真的没那么可怕。在本质上,它们是将函数作为参数并返回函数的函数。一个非常简单的示例打印调用的结果:

    >>> def my_decorator(function):
    ...  def inner_function(*args, **kwargs):
    ...    res = function(*args, **kwargs)
    ...    print("We have: "+res)
    ...    return res
    ...
    >>> @my_decorator
    ... def add(x, y):
    ...  return x+y
    ...
    >>> add(1,2)
    We have: 3
    3
    

    这相当于

    add = my_decorator(add)
    

    对于您的问题,装饰器只需覆盖函数的__doc__ 属性。

    >>> def frenchmeup(fun):
    ...    fun.__doc__ = "Bonjour, documentation!"
    ...    return fun
    ... 
    >>> @frenchmeup
    ... def foo():
    ...   """hello doc"""
    ...   return "world"
    ... 
    >>> foo.__doc__
    'Bonjour, documentation!'
    

    将参数传递给装饰器

    如果您必须为每个函数创建一个装饰器,这将非常繁重。您可以使用文档字典轻松开发通用解决方案:

    >>> ttable = {
    ...   "FR" : {
    ...     "hello doc": "Bonjour, documentation!"
    ...   }
    ... }
    >>> def document(lang=None):
    ...   def doc_decorator(function):
    ...     if lang and lang in ttable:
    ...       function.__doc__ = ttable[lang][function.__doc__]
    ...     return function
    ...   return doc_decorator
    ... 
    >>> @document(lang="FR")
    ... def foo():
    ...   """hello doc"""
    ...   return 42
    ... 
    >>> foo.__doc__
    'Bonjour, documentation!'
    

    不是现在装饰器是如何由函数生成的。这更复杂,但使您能够将参数传递给装饰器。

    作为个人说明,我花了一点时间才点击它,但我现在经常在我的 python 代码中使用它。

    自动文档字符串翻译策略

    您实际上可以通过检查模块中的文档字符串以编程方式生成文档字典。

    来自cmets:

    这个想法是字典是从您的文档字符串中自动生成的,然后传递给翻译器。如果您更改了规范(英语?)文档字符串,那么翻译也必须更改。通过将旧翻译表与新生成的表进行比较,您将能够重新插入规范文档字符串未更改的翻译。您只需添加新文档字符串的翻译。

    因此,例如,在将 foo() 文档字符串更改为 """goodbye, doc...""" 后,您将重新运行表生成器,您将获得一个新表,其中缺少旧的“hello doc”键和一个新键-值对 ("goodbye, doc...", "") 在您的翻译表中。

    对 cmd 模块使用 help_<cmd>() 样式的替代方法

    如果您更愿意使用 cmd 模块的 help_<cmd>() 样式作为文档,您可以使用相同的原理,将翻译存储在字典中,并根据帮助命令。

    【讨论】:

    • 好的,这与link 这个有什么关系?似乎这更容易一些;但是,您的解决方案似乎通常会更好,因为它允许我为开发人员文档目的以及用户帮助目的修改文档字符串。你都有些什么想法呢?看来您的答案更好,但还有其他我没有考虑的细节吗?
    • 这取决于您是否希望帮助文本来自文档字符串。如果这样做,那么上面的代码将为您节省一些时间,并且如果您将 LANG 声明为全局,则可以在程序初始化时对其进行配置。如果您更喜欢使用help_<cmd>() 样式,那么您可以使用与使用字典相同的原理来存储 i18n 并查找规范的英语帮助字符串。后一种方式不需要装饰器。
    • 我希望有一个常量列表(在一般的、非 Python 意义上),这些常量被分配给每种语言的单独字符串。在您提出的解决方案中,您让我根据函数的 .__doc__; 查询字典。但是,如果我更改英文文档字符串,我还必须更改其在字典中的对应键。是否可以使用 fn.__doc__ 变量作为字典键?如果是这样,你能在你的答案中更新这个吗?否则,我现在喜欢装饰器方法,因为它似乎减少了我的类中的方法数量。
    • 这个想法是字典是从您的文档字符串中自动生成的,然后传递给翻译器。如果您更改了规范(英语?)文档字符串,那么翻译也必须更改。通过将旧翻译表与新生成的表进行比较,您将能够重新插入规范文档字符串未更改的翻译。您只需添加新文档字符串的翻译。
    猜你喜欢
    • 1970-01-01
    • 2020-05-28
    • 1970-01-01
    • 2012-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-18
    • 2018-03-16
    相关资源
    最近更新 更多