ドキュストリングをプログラム的に設定するにはどうすればよいですか?

StackOverflow https://stackoverflow.com/questions/4056983

  •  27-09-2019
  •  | 
  •  

質問

関数を返すラッパー関数があります。返された関数のドキュストリングをプログラム的に設定する方法はありますか?書くことができたら __doc__ 私は次のことをします:

def wrapper(a):
    def add_something(b):
       return a + b
    add_something.__doc__ = 'Adds ' + str(a) + ' to `b`'
    return add_something

それから私はすることができました

>>> add_three = wrapper(3)
>>> add_three.__doc__
'Adds 3 to `b`

しかし、それ以来 __doc__ 読み取り専用です、私はそれをすることができません。正しい方法は何ですか?


編集:わかりました、私はこれをシンプルに保ちたかったのですが、もちろんこれは私が実際にやろうとしていることではありません。一般的に __doc__ 私の場合は、そうではありません。

テストケースを作成しようとしています unittest 自動的。のサブクラスであるクラスオブジェクトを作成するラッパー関数があります unittest.TestCase:

import unittest
def makeTestCase(filename, my_func):
    class ATest(unittest.TestCase):
        def testSomething(self):
            # Running test in here with data in filename and function my_func
            data  = loadmat(filename)
            result = my_func(data)
            self.assertTrue(result > 0)

    return ATest

このクラスを作成して、のドキュメントを設定しようとすると testSomething エラーが発生します:

>>> def my_func(): pass
>>> MyTest = makeTestCase('some_filename', my_func)
>>> MyTest.testSomething.__doc__ = 'This should be my docstring'
AttributeError: attribute '__doc__' of 'instancemethod' objects is not writable
役に立ちましたか?

解決

私はドックストリングを工場の関数に渡して使用します type クラスを手動で構築します。

def make_testcase(filename, myfunc, docstring):
    def test_something(self):
        data = loadmat(filename)
        result = myfunc(data)
        self.assertTrue(result > 0)

    clsdict = {'test_something': test_something,
               '__doc__': docstring}
    return type('ATest', (unittest.TestCase,), clsdict)

MyTest = makeTestCase('some_filename', my_func, 'This is a docstring')

他のヒント

an instancemethod そのドキュストリングを取得します __func__. 。のドキュストリングを変更します __func__ 代わりは。 ( __doc__ 関数の属性は書き込み可能です。)

>>> class Foo(object):
...     def bar(self):
...         pass
...
>>> Foo.bar.__func__.__doc__ = "A super docstring"
>>> help(Foo.bar)
Help on method bar in module __main__:

bar(self) unbound __main__.Foo method
    A super docstring

>>> foo = Foo()
>>> help(foo.bar)
Help on method bar in module __main__:

bar(self) method of __main__.Foo instance
    A super docstring

から 2.7ドキュメント:

ユーザー定義の方法

ユーザー定義のメソッドオブジェクトは、クラス、クラスインスタンス(またはなし)、および呼び出し可能なオブジェクト(通常はユーザー定義の関数)を組み合わせます。

特別な読み取り専用属性:IM_Selfはクラスインスタンスオブジェクト、IM_FUNCは関数オブジェクトです。 IM_CLASSは、バインドされたメソッドのIM_Selfのクラスまたはバインドメソッドの方法を要求したクラスです。 __doc__ メソッドのドキュメントです(と同じです im_func.__doc__); __name__ メソッド名です(と同じです im_func.__name__); __module__ モジュールの名前は、メソッドが定義されているか、利用できない場合は何も定義されていません。

バージョン2.2で変更されました:IM_Selfは、メソッドを定義したクラスを参照するために使用されます。

バージョン2.6で変更されました:3.0の前方互換性の場合、 IM_FUNCも利用できます __func__, およびim_self as __self__.

デコレーターを使用するだけです。これがあなたのケースです:

def add_doc(value):
    def _doc(func):
        func.__doc__ = value
        return func
    return _doc

import unittest
def makeTestCase(filename, my_func):
    class ATest(unittest.TestCase):
        @add_doc('This should be my docstring')
        def testSomething(self):
            # Running test in here with data in filename and function my_func
            data  = loadmat(filename)
            result = my_func(data)
            self.assertTrue(result > 0)

    return ATest

def my_func(): pass

MyTest = makeTestCase('some_filename', my_func)
print MyTest.testSomething.__doc__
> 'This should be my docstring'

同様のユースケースは次のとおりです。 Pythonダイナミックヘルプとオートコンプリート生成

これは、という事実への追加です __doc__ タイプのクラスの属性 type 変えられない。興味深い点は、クラスがタイプを使用して作成されている限り、これは真実であるということです。メタラスを使用するとすぐに、実際に変更することができます __doc__.

この例では、ABC(AbstractBaseClass)モジュールを使用しています。スペシャルを使用して動作します ABCMeta メタラス

import abc

class MyNewClass(object):
    __metaclass__ = abc.ABCMeta

MyClass.__doc__ = "Changing the docstring works !"

help(MyNewClass)

結果として生じます

"""
Help on class MyNewClass in module __main__:

class MyNewClass(__builtin__.object)
 |  Changing the docstring works !
"""

私はこれがコメントであるべきだと思いますが、それでも私の最初の50ポイントを集めています...

__doc__ オブジェクトがタイプ「タイプ」である場合にのみ、書くことはできません。

あなたの場合、 add_three 機能であり、設定するだけです __doc__ 任意の文字列に。

Unittest.testcaseサブクラスを自動的に生成しようとしている場合、より多くの走行距離がそれらをオーバーライドする可能性があります 簡単な説明 方法。

これは、通常のユニテスト出力で見られるように、基礎となるドックストリングを最初の行まで削除する方法です。これは、TeamCityのようなレポートツールに現れたものを制御するのに十分であり、これが必要なものでした。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top