4

func_docに(式として)を設定したいと思います。 def

def f():
    '''My function help''' #Set the docstring

def g():
    "My function " + "help" # An expression, so not read as a docstring
    # can I put something here to set the docstring as an expression?
g.func_doc # is None
g.func_doc = "My function " + "help" # This works

これは可能ですか?

(これを行う理由として考えられるのは、モジュールから関数をインポートすること (および docstring もインポートすること) とlexerを使用することの 2 つです。)

4

4 に答える 4

5

文字列リテラルのみがdocstringとして認識されるため、これはできません。ただし、デコレータを使用して、関数のドキュメント文字列を設定または変更できます。(実行可能コードで明示的に変更することもできます__doc__が、デコレーターは論理的に宣言の一部であるため、はるかにクリーンです)。

これは、たとえば、docstring (の一部) と同じテキストを含む関数がいくつかある場合に役立ちます。関数の宣言された docstring に引数 (リテラルまたは変数) を追加する小さなデコレータを次に示します。

def docstring(docstr, sep="\n"):
    """
    Decorator: Append to a function's docstring.
    """
    def _decorator(func):
        if func.__doc__ == None:
            func.__doc__ = docstr
        else:
            func.__doc__ = sep.join([func.__doc__, docstr])
        return func
    return _decorator

次のように使用できます。

@docstring("copyright by nobody")
def testme():
    "This function does nothing"
    pass

または、既存の関数 (おそらく別のモジュールからインポートされたもの) を変更するために、直接実行することもできます。

from re import sub
docstring("Copyright unknown")(sub)
于 2012-08-31T15:46:47.673 に答える
1

それはいけません。ルールは次のとおりです。最初のステートメントとしての文字列リテラルは、docstring として取得されます。式の場合、文字列リテラルではないため無視されます。

本当に必要な場合は、後で docstring 属性に明示的に割り当てることもできます。なぜあなたがそれを必要とするのかわかりません。あなたの理由は私には怪しいようです:

  • 関数 (または実際にはその他のもの) をインポートすると、同じ docstring を持つまったく同じオブジェクトが得られます。関数をラップすることは別の話ですが、私たちが持っているものについてはfunctools.wraps.
  • 正規表現の一部を別の変数に分解しても、それ自体が読みやすくなるわけではありません。トークンの定義を手元に置くことは、アクション コードを理解するために不可欠です。
于 2012-08-31T15:44:17.547 に答える
1

いいえ、関数の本体内から関数の docstring を設定することはできません。関数の外部または関数内でコードを実行する必要があります (最初に関数を呼び出す必要があります)。

Python が通常 docstring を設定する方法は、関数スイートの最初の行 (行の下にインデントされたすべてdef)を取得することです。それが文字列リテラルの場合、スイートからそれを削除し、docstring にします。その後、Python はスイートの残りを関数コード オブジェクトにfunction()コンパイルし、コンパイルされたコード オブジェクトと docstring (とりわけ) を渡すことによって新しいオブジェクトを作成します。

代わりにたまたま文字列を生成する式を使用すると、その「トリック」は機能しません。python はその式を無視し、コンパイルする関数スイートの一部として残します。関数スイート自体はコンパイルされ実行されないため、コンパイル時に関数オブジェクトで使用される docstring に「手を伸ばして」設定することはできません。

関数のdocstring を動的に設定できる唯一__doc__の方法は、関数オブジェクトを直接参照し、そのまたはfunc_doc変数を設定することです (この 2 つはエイリアスです)。確かに、それは関数スイートで行うことができますが、それはかなり無意味です。そうするまで、docstring は間違っています。

モジュールから関数をインポートすると、すでにドキュメント文字列も取得されていることに注意してください。

>>> import itertools
>>> print itertools.groupby.__doc__
groupby(iterable[, keyfunc]) -> create an iterator which returns
(key, sub-iterator) grouped by each value of key(value).

docstring を個別にインポートする必要はありません。

于 2012-08-31T15:45:41.470 に答える
0

__doc__実行時に関数の属性を変更できます。

>>> def what():
...    """docstring"""
...    what.__doc__ += " x"
...    print what.__doc__
... 
>>> what()
docstring x
>>> what()
docstring x x
>>> what()
docstring x x x
>>> what()
docstring x x x x
于 2012-08-31T17:09:18.490 に答える