如何确保Python中的参数类型正确?

umb*_*ter 3 python

我是Python新手,我想弄清楚是否有办法在参数定义中指定变量类型.例如:

def function(int(integer))
Run Code Online (Sandbox Code Playgroud)

而不是:

def function(integer)
    int(integer)
Run Code Online (Sandbox Code Playgroud)

我知道这不是一个主要的区别,但我试图在这里使用良好的编程实践,如果我定义一个具有大量参数的函数,它可能会变得混乱.

Azs*_*sgy 10

Python使用Duck类型,这意味着您不应该根据它们的类型来区分对象,而是基于它们具有的属性和功能.这具有许多优点,这些优点超出了本答案的范围.

如果要在函数中添加文档,则应该使用文档字符串

def square(x):
    """takes a number and squares it"""
    return x**2
Run Code Online (Sandbox Code Playgroud)

键入提示

def square(x: int) -> int:
    """takes a number and squares it"""
    return x**2
Run Code Online (Sandbox Code Playgroud)

如果你真的需要检查给你的参数,你可以做一个hasattr()检查参数提供的属性和函数.在大多数情况下(包括这个),只是不检查类型更好

def square(x):
    """takes a number and squares it"""
    if not hasattr(x, "__pow__"):
         raise TypeError("unsupported operand:", type(x))

    return x**2
Run Code Online (Sandbox Code Playgroud)


Sim*_*ser 9

从Python 3.4开始,您可以向函数或方法添加类型注释:

def function(a: int):
    pass
Run Code Online (Sandbox Code Playgroud)

但是,这些类型不会强制执行 - 您仍然可以使用非整数值调用该函数.

此外,Python基于duck typing的概念,因此有时您可能希望接受各种类型,例如两者intfloat特定函数.

  • 这个答案可以通过直接解决这个问题来改进。正如所写的那样,它似乎通过提及似乎应该起作用但不起作用的东西来诱骗答案。 (4认同)

Ily*_*rov 6

如果你想使用语法

def function(a: int):
    pass
Run Code Online (Sandbox Code Playgroud)

@SimeonVisser 提到并且你有 python3.5,你可以使用我写的装饰器

from typing import get_type_hints

def strict_types(f):
    def type_checker(*args, **kwargs):
        hints = get_type_hints(f)

        all_args = kwargs.copy()
        all_args.update(dict(zip(f.__code__.co_varnames, args)))

        for key in all_args:
            if key in hints:
                if type(all_args[key]) != hints[key]:
                    raise Exception('Type of {} is {} and not {}'.format(key, type(all_args[key]), hints[key]))

        return f(*args, **kwargs)

    return type_checker
Run Code Online (Sandbox Code Playgroud)

在定义这样的函数时

@strict_types
def concatenate_with_spam(text: str) -> str:
    return text + 'spam'
Run Code Online (Sandbox Code Playgroud)

如果传递给函数的参数类型错误,它将引发异常。

Traceback (most recent call last):
  File "strict_types.py", line 23, in <module>
    concatenate_with_spam(1)
  File "strict_types.py", line 13, in type_checker
    raise Exception('Type of {} is {} and not {}'.format(key, type(all_args[key]), hints[key]))
Exception: Type of text is <class 'int'> and not <class 'str'>
Run Code Online (Sandbox Code Playgroud)

尽管我还没有实施一种方法来检查您返回的内容的类型,但如果您也想检查它,则此解决方案不适合您。

  • 我很惊讶这没有得到更多的支持。它可能不是真正的Pythonic,但它正是按照要求做的。我还自己编写了一个具有此功能的装饰器,最终得到了与此处提供的几乎完全相同的代码。 (2认同)