関数を返すラッパー関数があります。返された関数の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
このクラスを作成してtestSomething
のdocstringを設定しようとすると、エラーが発生します。
>>> 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
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')
instancemethod
は、その__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 docs から:
ユーザー定義メソッド
ユーザー定義メソッドオブジェクトは、クラス、クラスインスタンス(または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は
__func__
、としても、im_selfは__self__
としても使用できます。
これは、タイプtype
のクラスの__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ポイントを集めています...
デコレータを使用するだけです。これがあなたのケースです:
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'の場合にのみ書き込み可能ではありません。
あなたの場合、add_three
は関数であり、__doc__
を任意の文字列に。
Unittest.TestCaseサブクラスを自動的に生成しようとしている場合、それらの shortDescription メソッドをオーバーライドすることで、より多くの距離が得られる可能性があります。
これは、通常のユニットテストの出力に見られるように、基礎となるdocstringを最初の行まで削除するメソッドです。それをオーバーライドすることで、TeamCityなどのレポートツールに表示されるものを制御するのに十分でした。