単一のモジュール/機能のための1つの以上のドキュメンテーション文字列など?
質問
私は、Python 3.1を使用しています。
これは、単一のモジュールまたは機能のために1つのドキュメンテーション文字列よりも多くを作成することは可能ですか? 私は、プログラムを作成しています、と私はそれぞれのカテゴリで複数のドキュメンテーション文字列を持っているつもりです。私は、プログラム自体の中のドキュメントのdocstringへの参照を入れている、彼らはそれを使用することができ、そして同様プログラマと非プログラマのため物事が容易にするので、他の人にプログラムを提供していきます。
具体的には、私はインターフェイスとしてプログラム/モジュールのメニューを持っている、とのいずれかのオプションは、プログラムのドキュメント用のモジュールのドキュメンテーション文字列へのアクセスを許可します。それが可能だ場合はこのように、私は、ドキュメントの種類を分類するために、複数のドキュメンテーション文字列を作りたいです。彼らは文書の一部を見たいのであれば、それはユーザーに容易になるだろう。
など。最初のdocstringは、プログラムを使用する方法について説明します。第二にドキュメンテーション文字列は、プログラムの一部がどのように機能するかについての情報が含まれています。第三のdocstringは、別の部分がどのように機能するかについての情報が含まれています。など。
これは可能ですか?そしてもしそうなら、どのようにそれらを参照しますか。
アップデート:コメントを追加しました。
。私の独創的な考えは、実際の意味で、複数のドキュメント文字列を持っていることでした
def foo():
"""docstring1: blah blah blah"""
"""docstring2: blah blah blah"""
pass # Insert code here
それから私は私がこれらのドキュメンテーション文字列のそれぞれを参照することを可能にするために使用できるいくつかのコードが存在することになります。 だから、私は、これはその後、不可能であることを推測している?
解決
私はドキュメンテーション文字列を持つ複雑な何かをしようとしているお勧めしません。シンプルなドキュメンテーション文字列を維持し、あなたは別のドキュメントのオプションの束を使用できるようにしたい場合は何かを行うことをお勧めます。
あなたは本当にあなたが述べた何をしたい場合は、私はあなたがドキュメンテーション文字列内のセクションを区切るためにタグを使用することをお勧め。これと同様ます:
def foo(bar, baz):
"""Function foo()
* Summary:
Function foo() handles all your foo-ish needs. You pass in a bar and a baz and it foos them.
* Developers:
When you change foo(), be sure you don't add any global variables, and don't forget to run the unit tests.
* Testers:
When you test foo, be sure to try negative values for baz.
"""
pass # code would go here
そして、あなたはかなり簡単にチャンクにあなたの文字列を分割することができ、ユーザーがメニュー項目を選択したとき、ちょうど適切なチャンクを表示します。
s = foo.__doc__ # s now refers to the docstring
lst = s.split("\n* ")
section = [section for section in lst if section.startswith("Developers")][0]
print(section) # prints the "Developers" section
この方法で、あなたが対話的なPythonシェルで作業しているとき、あなたは「ヘルプ(FOO)」と言うことができますし、すべてのドキュメンテーション文字列が表示されます。そして、あなたのコードを勉強しようとしている他の人に陥ることになる、パイソンの基本的な部分の基本的な動作を変更されていません。
あなたは、さらに単純な何か行うことができます:。ただ、異なる目的のためにドキュメンテーション文字列の大きな世界的な辞書を作り、それぞれの新しいもののためのソースコードから、それを更新します。
doc_developers = {} doc_testers = {}
def foo(bar, baz):
"""Function foo()
Function foo() handles all your foo-ish needs. You pass in a bar and a baz and it foos them."
pass # code goes here
doc_developers["foo"] = "When you change foo(), be sure you don't add any global variables, and don't forget to run the unit tests."
doc_testers["foo"] = "When you change foo(), be sure you don't add any global variables, and don't forget to run the unit tests."
一度実際def
にし、辞書の更新行ごとに一度:私はこれについて好きではない最大のものは、あなたが関数fooの名前を変更した場合、あなたが複数の場所でそれを変更する必要があるだろう、ということです。しかし、あなたは、ほとんどの機能を書き込むことによって、これを修正できます:
def doc_dict = {} # this will be a dict of dicts
doc_dict["developers"] = {}
doc_dict["testers"] = {}
def doc_update(fn, d):
name = fn.__name__
for key, value in d.items():
doc_dict[key][name] = value
def foo(bar, baz):
"""Function foo()
Function foo() handles all your foo-ish needs. You pass in a bar and a baz and it foos them."
pass # code goes here
d = { "developers": "When you change foo(), be sure you don't add any global variables, and don't forget to run the unit tests.",
"testers": " When you test foo, be sure to try negative values for baz."}
doc_update(foo, d)
があり(doc_updateオンにする方法はデコレータに)おそらくですが、私は今の時間外です。
他のヒント
あなたはデコレータがきれい〜unutbuが何であるかを行うためにを使用することを検討したいです機能のための提案:それぞれごとに別々のフィールドを追加します。たとえばます:
def human_desc(description):
def add_field(function):
function.human_desc = description
return function
return add_field
これはアクションでhuman_desc
は次のようになります。
@human_desc('This function eggfoobars its spam.')
def eggfoobar(spam):
"Apply egg, foo and bar to our spam metaclass object stuff."
print spam
<時間>
、について説明の
DOCはに説明したように、、コードのビットであります以下に相当します:
def eggfoobar(spam):
"Apply egg, foo and bar to our spam metaclass object stuff."
print spam
eggfoobar = human_desc('This function eggfoobars its spam.')(eggfoobar)
とhuman_desc('This function eggfoobars its spam.')
次の関数を返します:
def add_field(function):
function.human_desc = 'This function eggfoobars its spam.'
return function
あなたはhuman_desc
を見ることができるようにあなたが引数として渡すdescription
の値について上記のデコレータを生成する関数です。デコレータ自体が装飾されるべき機能(修正)を受け入れ、それは(この場合には、それは余分なメタデータのビットを加えて、)で装飾された返す関数です。要するに、これは同等です。
def eggfoobar(spam):
"Apply egg, foo and bar to our spam metaclass object stuff."
print spam
eggfoobar.human_desc = 'This function eggfoobars its spam.'
の構文は、しかし、はるかにクリーンであるエラーが発生しにくい。
もちろん、いずれかの方法で、どのようなあなたが得ることはあります:
>>> print eggfoobar.human_desc
This function eggfoobars its spam.
の代わりに関数を使用すると、あなたが定義したusage
とextra
属性を持つクラスを使用することができます。たとえば、
class Foo(object):
'''Here is the function's official docstring'''
usage='All about the usage'
extra='How another part works'
def __call__(self):
# Put the foo function code here
pass
foo=Foo()
あなたはいつものようにそれを呼びたい:foo()
、
そして、あなたはこのように、公式ドキュメント文字列、および代替ドキュメンテーション文字列を取得することができます:
print foo.__doc__
print foo.usage
print foo.extra
また、(代わりに私が上記したようクラスを使用する)、プレーン機能への追加の属性を付けることができますが、私は構文は少し醜いだと思います:
def foo():
pass
foo.usage='Usage string'
foo.extra='Extra string'
そして、モジュールはあまりにもオブジェクトです。彼らは同じように簡単に余分な属性を持つことができます:
あなたはモジュールの定数を定義する場合
USAGE='''blah blah'''
EXTRA='''meow'''
そして、あなたはモジュールをインポートするときます:
import mymodule
は、
と公式と代替ドキュメンテーション文字列にアクセスすることができますmymodule.__doc__
mymodule.USAGE
mymodule.EXTRA
あなたは__doc__
属性を置き換えることができますが、すべてのタイプのための十分な柔軟性初期ドキュメンテーション文字列にすることを検討してください。
モジュールのクラス/関数/モジュールの集合体です。だから、そのドキュメント文字列は、それが含まれているかについてのイントロを与えます。
クラスのドキュメンテーション文字列は、クラスは約であり、そのメソッドのドキュメンテーション文字列がどのような方法教えて何を伝えます。クラスは1つの目的を果たすと方法は、彼らは、単一のドキュメンテーション文字列を持っている必要がありますので、一つのことを行います。
関数は、一つのことを行いますので、1 doctringは彼らのために十分です。
私は、複数のドキュメンテーション文字列がどのような目的を十分でしょう見ることができません。たぶん、あなたのモジュールは大きいです。サブモジュールに、モジュールの言及サブモジュールのドキュメント文字列に分割します。