12

関数への引数が特定の (または同等の) 構造体であると予想される場合、Python のlist, tupleandを使用して構築されます。どのように、dictどこ文書化する必要がありますか?

ドキュメントの例:

def foo(bar):
    """
    Args:
        bar: 2-tuple, ([(<mapping>,<number>), ...], <string>)
    """
    pass

少し面倒です。いくつかの問題:

  • 構造が読みにくい
  • 構造の各要素の意味を示すのが難しい
  • 不定長の表記方法
  • 一度だけ文書化するか、どこにでも文書化するか
  • 編集:ダックタイピングが要素に問題ないことを明確に示す方法 (つまり、「dict」と「mapping-like」)

編集:この例は、型を強制しようとするものではなく、構造を文書化しようとしています。その点、大丈夫duck typingです。

4

6 に答える 6

4

私は仕事中にこの問題に遭遇しました。私の個人的な調査 (Google で十分に調べた結果) によると、複雑で入れ子になった関数の引数を文書化するための標準はありません。私は最終的に、データ構造の要素<>を表すために使用するアプローチを発明し、各要素はドキュメント内で独自のヘッダーと段落を取得します。例えば:

<options>
---------

A mapping:

  {'years':<years>,
   'states':<states>}

This is the root level of the `options` argument.

<years>
-------

A sequence of integers, each of which is a year to be included in the analysis.


<states>
--------

A sequence of strings, each of which is a state to be included in the analysis.

このドキュメントは、関数のドキュメント文字列に含めることができますが、私の場合は別のドキュメントに分割することにしました。このアプローチは、より複雑な構造に拡張できます。たとえば、こちらのドキュメントを参照してください。

于 2013-02-12T19:36:52.737 に答える
1

Python 3 を使用している場合は、「関数の注釈」に関心があるかもしれません。それらは強制されておらず、完全にオプションですが、あなたが望むことをしているようです。注釈は任意の Python 式にすることができ、引数の横の関数ヘッダーに含まれます。例(少し無意味で申し訳ありません):

def fn(name: str, age: int, hobbies: "something else goes here") -> max(2, 9):
  # la la la
  return 9

詳細 (可能なユースケースと例を含む) はこちら: PEP 3107

于 2013-02-12T06:44:05.193 に答える
1

あなたの質問に対する私の簡単な答えは、Zen of Pythonを引用することです: 「明示的は暗黙的よりも優れています」 . あなたの質問に関して言えば、これは、単一の引数を文書化するのに段落全体が必要であっても、必要なものを正確に完全に書き出すことを意味します。python docs を読んで例を確認してください。特定のケースでは、タプルではなくシーケンスを参照することでダックタイピングを示すことができます( http://docs.python.org/2/library/collections.html#collections-abstract-base-classesを参照)。

于 2013-02-12T06:10:35.573 に答える
0

これまでで最も気に入らなかった function には、本当に優れたインライン ドキュメントがあったと思います。

validateここのドキュメントをチェックしてください:

Pylons デコレータ - 検証 - GitHub

def validate(schema=None, validators=None, form=None, variable_decode=False,
         dict_char='.', list_char='-', post_only=True, state=None,
         on_get=False, **htmlfill_kwargs):
"""Validate input either for a FormEncode schema, or individual
validators

Given a form schema or dict of validators, validate will attempt to
validate the schema or validator list.

If validation was successful, the valid result dict will be saved
as ``self.form_result``. Otherwise, the action will be re-run as if
it was a GET, and the output will be filled by FormEncode's
htmlfill to fill in the form field errors.

``schema``
    Refers to a FormEncode Schema object to use during validation.
``form``
    Method used to display the form, which will be used to get the
    HTML representation of the form for error filling.
``variable_decode``
    Boolean to indicate whether FormEncode's variable decode
    function should be run on the form input before validation.
``dict_char``
    Passed through to FormEncode. Toggles the form field naming
    scheme used to determine what is used to represent a dict. This
    option is only applicable when used with variable_decode=True.
``list_char``
    Passed through to FormEncode. Toggles the form field naming
    scheme used to determine what is used to represent a list. This
    option is only applicable when used with variable_decode=True.
``post_only``
    Boolean that indicates whether or not GET (query) variables
    should be included during validation.

    .. warning::
        ``post_only`` applies to *where* the arguments to be
        validated come from. It does *not* restrict the form to
        only working with post, merely only checking POST vars.
``state``
    Passed through to FormEncode for use in validators that utilize
    a state object.
``on_get``
    Whether to validate on GET requests. By default only POST
    requests are validated.

Example::

    class SomeController(BaseController):

        def create(self, id):
            return render('/myform.mako')

        @validate(schema=model.forms.myshema(), form='create')
        def update(self, id):
            # Do something with self.form_result
            pass

"""
于 2013-02-07T21:00:42.997 に答える
0

デコレータを使用して型を強制し、それをドキュメント化することもできます。

def require(arg_name, *allowed_types):
    '''
    example:
    @require("x", int, float)
    @require("y", float)
    def foo(x, y):
        return x+y
    '''
    def make_wrapper(f):
        if hasattr(f, "wrapped_args"):
            wrapped_args = getattr(f, "wrapped_args")
        else:
            code = f.func_code
            wrapped_args = list(code.co_varnames[:code.co_argcount])

        try:
            arg_index = wrapped_args.index(arg_name)
        except ValueError:
            raise NameError, arg_name
        def wrapper(*args, **kwargs):
            if len(args) > arg_index:
                arg = args[arg_index]
                if not isinstance(arg, allowed_types):
                    type_list = " or ".join(str(allowed_type) for allowed_type in allowed_types)
                    raise Exception, "Expected '%s' to be %s; was %s." % (arg_name, type_list, type(arg))
            else:
                if arg_name in kwargs:
                    arg = kwargs[arg_name]
                    if not isinstance(arg, allowed_types):
                        type_list = " or ".join(str(allowed_type) for allowed_type in allowed_types)
                        raise Exception, "Expected '%s' to be %s; was %s." % (arg_name, type_list, type(arg))

            return f(*args, **kwargs)

        wrapper.wrapped_args = wrapped_args
        return wrapper

    return make_wrapper        
于 2013-02-07T18:00:09.343 に答える
0

私が見た中で最も完全な docstring 仕様はNumPy Docstring Style Guideですが、あなたの質問をカバーするための詳細を提供していないことに同意します. そのため、現時点では、あなたの(そして私自身の)質問に答える標準が存在しない可能性があると示唆するかもしれません.

于 2013-02-07T18:12:27.230 に答える