Function parameter dtype declaring doesnt work?

前端 未结 1 952
执笔经年
执笔经年 2021-01-27 03:47

Why doesnt this give back \'12\'?
The \'+\' sign should concatenate two strings, not add them.

def foo(a:str, b:str):
    print(a+b)
foo(1,2)
3
相关标签:
1条回答
  • 2021-01-27 04:43

    That's not what annotations are for. Annotations are metadata, not an instruction to Python to convert data.

    From the Function definitions reference documentation:

    Parameters may have annotations of the form “: expression” following the parameter name. Any parameter may have an annotation even those of the form *identifier or **identifier. Functions may have “return” annotation of the form “-> expression” after the parameter list. These annotations can be any valid Python expression and are evaluated when the function definition is executed. Annotations may be evaluated in a different order than they appear in the source code. The presence of annotations does not change the semantics of a function.

    (Bold emphisis mine).

    For example, the Python type hinting framework uses annotations to attach type information to functions for static analysis, validating that code actually passes in the types that are expected to be passed in.

    Just convert your values explicitly; in the call:

    foo(str(1), str(2))
    

    or in the function itself:

    def foo(a, b):
        print(str(a) + str(b))
    

    or in a decorator:

    import functools
    import inspect
    
    def typeconversion(f):
        """Converts arguments with a callable attached in the parameter annotation"""
        sig = inspect.signature(f)
    
        @functools.wraps(f)
        def wrapper(*args, **kwargs):
            # convert any argument (including defaults), for which there is a
            # callable annotation
            bound = sig.bind(*args, **kwargs)
            bound.apply_defaults()
            args = bound.arguments
            for param in sig.parameters.values():
                if param.annotation is not param.empty and callable(param.annotation):
                    args[param.name] = param.annotation(args[param.name])
    
            # call the function with the converted arguments
            result = f(*bound.args, **bound.kwargs)
    
            # convert the return value
            if sig.return_annotation is not sig.empty and callable(sig.return_annotation):
                result = sig.return_annotation(result)
    
            return result
        return wrapper
    

    Demo:

    >>> @typeconversion
    ... def foo(a: str, b: str) -> int:
    ...     return a + b
    ...
    >>> foo(42, 101)
    42101
    
    0 讨论(0)
提交回复
热议问题