62

関数を返すラッパー関数があります。返された関数の docstring をプログラムで設定する方法はありますか? 私が書くことができるなら、私は__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

このクラスを作成して docstring を設定しようとすると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
4

6 に答える 6

56

は、instancemethodからdocstringを取得します__func____func__代わりにのdocstringを変更してください。(__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ドキュメントから:

ユーザー定義のメソッド

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

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

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

バージョン2.6で変更:3.0の上位互換性のために、 im_funcは、として im_selfはとしても使用できます __func____self__

于 2011-01-29T06:41:15.017 に答える
22

docstring をファクトリ関数に渡し、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')
于 2010-10-30T02:47:44.617 に答える
11

__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 !
"""
于 2016-01-21T21:45:38.237 に答える
9

デコレータを使用するだけです。あなたの場合は次のとおりです。

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 の動的ヘルプとオートコンプリートの生成

于 2012-11-28T10:49:12.760 に答える
5

__doc__オブジェクトのタイプが「type」の場合にのみ書き込み可能ではありません。

あなたの場合、add_threeは関数であり、__doc__任意の文字列に設定できます。

于 2010-10-30T02:28:18.633 に答える
0

unittest.TestCaseサブクラスを自動的に生成しようとしている場合、shortDescriptionメソッドをオーバーライドすることで、より多くのマイレージが得られる可能性があります。

これは、通常の unittest 出力に見られるように、基礎となる docstring を最初の行まで削除するメソッドです。これをオーバーライドするだけで、必要だった TeamCity などのレポート ツールに表示される内容を制御できるようになりました。

于 2014-01-07T10:20:09.700 に答える