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

Posted

技术标签:

【中文标题】如何确保 Python 中的参数类型正确?【英文标题】:How do I ensure parameter is correct type in Python? 【发布时间】:2021-03-10 21:27:41 【问题描述】:

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

def function(int(integer))

相对于:

def function(integer)
    int(integer)

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

【问题讨论】:

不,python 中没有类型检查,您实际上是在说类型检查还是从可以转换为 int 的东西转换? 相关:What's the Canonical Way to Check for Type in Python 你的问题让我相信你没有采用 Pythonic 方法来解决你的问题。 Python 是动态类型的,您的解决方案应该灵活地利用这一点。 isinstance(some_variable, int) 你为什么需要这个? 【参考方案1】:

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

def function(a: int):
    pass

但是这些类型不是强制的 - 您仍然可以使用非整数值调用函数。

此外,Python 基于鸭子类型的思想,因此您有时可能希望接受多种类型,例如特定函数的 intfloat

【讨论】:

可以通过直接解决问题来改进此答案。正如所写的那样,它似乎通过提及似乎应该有效但没有用的东西来诱饵和转换答案。【参考方案2】:

如果你想使用语法

def function(a: int):
    pass

@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

同时定义类似的函数

@strict_types
def concatenate_with_spam(text: str) -> str:
    return text + 'spam'

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

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'>

虽然我还没有实现一种方法来检查你返回的类型,如果你也想检查它,这个解决方案也不适合你。

【讨论】:

我认为简单的断言语句来断言每个参数的类型效果更好! 我很惊讶这没有得到更多的支持。它可能不是真正的pythonic,但它完全按照要求做。我还自己编写了一个具有此功能的装饰器,并最终得到了与此处提供的几乎完全相同的代码。 我一直在寻找这样的东西。我最终写了一些不太相似的东西,但如果提供的参数不正确,它会弹出一个默认值。【参考方案3】:

Python 使用Duck typing,这意味着您不应根据对象的类型来区分对象,而应根据它们具有的属性和功能来区分对象。这具有许多超出此答案范围的优点。

如果你想在你的函数中添加文档,你应该做的是使用docstring

def square(x):
    """takes a number and squares it"""
    return x**2

和type hints

def square(x: int) -> int:
    """takes a number and squares it"""
    return x**2

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

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

    return x**2

【讨论】:

以上是关于如何确保 Python 中的参数类型正确?的主要内容,如果未能解决你的问题,请参考以下文章

Python中的多线程如何正确运用?案例详解

阐明自变量、参数和类型如何工作

python-函数可变参数类型

如何正确验证powershell中的参数?

如何根据 Python 中的子类类型定义基类参数?

python 函数的参数的几种类型