在平面方法中编辑__doc__吗?

时间:2019-09-04 19:34:03

标签: python python-3.x

我正在尝试围绕我编写的api做一个超薄的cli包装器。好像__doc__ dunder attr是在导入时设置的。

>>> def foo():
...     """
...     doc
...     """
...     pass
...
>>> foo.__doc__
'\n\tdoc\n\t'

我发现我可以在方法中更改__doc__

>>> def foo():
...     foo.__doc__ = "new doc"
...
>>> foo.__doc__
>>> foo()
>>> foo.__doc__
'new doc'

但这需要运行该方法。

我正在编写一个click工具,这允许file.py --help打印该文档。但是,因为这是一个薄包装器,所以最好将__doc__编辑为与doc内部调用的任何方法相同。

  

API.py

class FOO:
    def bar():
        """
        Some long doc string
        """
        pass
  

cli.py

import click

import API

@click.command()
def hello():
    """
    not what I want
    """
    hello.__doc__ = API.FOO.bar.__doc__
    API.FOO.bar()


if __name__ == '__main__':
    print(hello.__doc__)
    hello()
    print(API.FOO.bar.__doc__)

运行pyhton3.6 cli.py

时,我得到以下信息...
not what I want


Some long doc string

当我运行python3.6 cli.py --help

Usage: cli.py [OPTIONS]

  not what I want

Options:
  --help  Show this message and exit.

是否可以将导入方法中的doc字符串注入到click方法中?装饰器也许在导入时解析,但是我不确定该怎么做。谢谢。

2 个答案:

答案 0 :(得分:1)

如果您将对doc的更改实现为函数的修饰符,它将在导入时运行。

new Container(
  margin: EdgeInsets.only(right: 10, top: 15),
  child: new GestureDetector(
    child: isFavorite == 1 ? 
      new Image.asset(
      "assets/images/favorite.png",
      fit: BoxFit.contain,
      height: 35,
      width: 70,
      )
      : new Image.asset(
      "assets/images/unfavorite.png",
      fit: BoxFit.contain,
      color: Colors.white,
      height: 35,
      width: 70,
    ),

     onTap: () async {
       if (isLogin == true){
         if(isFavorite == 0) {
           getIsLikeAccommodation(accommodation.id , 1 );
         }
       else {
       getIsLikeAccommodation( accommodation.id , 0 );
     }
   }
  else {
     // safeye vorod be narm afzar bala biad
       }
     },
 )
),

答案 1 :(得分:1)

因此,一般的想法是您希望能够使用API.FOO.bar并为其命名包装。没问题,尽管需要一些开箱即用的思维。这里的关键思想是要理解装饰器也可以用作普通函数,将一个函数转换为另一个:

def wrap_api(method):
    result = click.command(method)
    result.__doc__ = method.__doc__
    return method

现在我们可以创建包装器了:

hello = wrap_api(API.FOO.bar)