在Python中,确保函数输入类型的正确性是一个常见的需求。传统的做法是使用isinstance()
函数进行检查,但这种方式可能会使代码显得冗长且不够优雅。以下是几种更优雅的方法:
Python 3.5 引入了类型注解,可以在函数定义中指定参数和返回值的预期类型。虽然类型注解本身并不会强制类型检查,但可以结合mypy
等第三方工具进行静态类型检查。
def greet(name: str) -> str:
return f"Hello, {name}!"
typing
模块typing
模块提供了更多的类型注解工具,例如List
, Dict
, Tuple
等,可以使代码更加清晰。
from typing import List
def sum_numbers(numbers: List[int]) -> int:
return sum(numbers)
可以编写自定义装饰器来检查函数参数的类型,这样可以使类型检查代码与业务逻辑分离,使代码更加简洁。
from functools import wraps
from typing import Any, Callable, TypeVar, cast
T = TypeVar('T')
def type_check(func: Callable[..., Any]) -> Callable[..., Any]:
@wraps(func)
def wrapper(*args, **kwargs):
sig = inspect.signature(func)
bound_args = sig.bind(*args, **kwargs)
for name, value in bound_args.arguments.items():
param = sig.parameters[name]
if param.annotation != param.empty and not isinstance(value, param.annotation):
raise TypeError(f"Argument '{name}' must be of type {param.annotation}")
return func(*args, **kwargs)
return wrapper
@type_check
def greet(name: str) -> str:
return f"Hello, {name}!"
enforce
库enforce
是一个第三方库,可以自动检查函数参数和返回值的类型。
from enforce import runtime_validation, config
config(dict(mode='covariant'))
@runtime_validation
def greet(name: str) -> str:
return f"Hello, {name}!"
@type_check
def greet(name: str) -> str:
if not name:
raise ValueError("Name cannot be empty")
return f"Hello, {name}!"
inspect
模块来获取函数的签名,并手动进行类型检查。import inspect
def type_check(func):
sig = inspect.signature(func)
def wrapper(*args, **kwargs):
bound_args = sig.bind(*args, **kwargs)
for name, value in bound_args.arguments.items():
param = sig.parameters[name]
if param.annotation != param.empty and not isinstance(value, param.annotation):
raise TypeError(f"Argument '{name}' must be of type {param.annotation}")
return func(*args, **kwargs)
return wrapper
通过以上方法,可以在Python中实现更优雅的类型检查,提高代码的可读性和健壮性。
领取专属 10元无门槛券
手把手带您无忧上云