如何在python中记录结构?

n61*_*007 10 python documentation docstring data-structures

如果一个参数传递给函数有望得到一定(或同等学历)的结构,使用python的内置list,tuple以及dict,如何在那里它应该被记录?

示例文档:

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

有点麻烦; 一些问题:

  • 结构很难读
  • 难以表示结构中每个元素的语义含义
  • 如何表示不固定长度
  • 是否应该只记录一次或任何地方
  • 编辑:如何清楚地表明鸭子打字对于一个元素是好的(即"dict"与"类似映射")

编辑:该示例不是为了尝试强制执行类型,而是尝试记录结构.对于这一点,duck typingOK.

era*_*ran 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        
Run Code Online (Sandbox Code Playgroud)