我知道,类型检查函数参数在Python中通常是不受欢迎的,但我认为我已经提出了这样做的情况.
在我的项目中,我有一个抽象基类Coord,有一个子类Vector,它有更多的功能,如旋转,变化幅度等.数字的列表和元组也将返回True,因为isinstance(x, Coord).我还有许多函数和方法接受这些Coord类型作为参数.我已经设置了装饰器来检查这些方法的参数.这是一个简化版本:
class accepts(object):
def __init__(self, *types):
self.types = types
def __call__(self, func):
def wrapper(*args):
for i in len(args):
if not isinstance(args[i], self.types[i]):
raise TypeError
return func(*args)
return wrapper
Run Code Online (Sandbox Code Playgroud)
这个版本非常简单,它仍然有一些bug.它就是为了说明这一点.它将被用作:
@accepts(numbers.Number, numbers.Number)
def add(x, y):
return x + y
Run Code Online (Sandbox Code Playgroud)
注意:我只是针对Abstract Base Classes检查参数类型.
这是一个好主意吗?有没有更好的方法来做到这一点,而不必在每个方法中重复类似的代码?
编辑:
如果我要做同样的事情,但不是事先在装饰器中检查类型,我会在装饰器中捕获异常:
class accepts(object):
def __init__(self, *types):
self.types = types
def __call__(self, func):
def wrapper(*args):
try:
return func(*args)
except TypeError:
raise TypeError, message
except AttributeError:
raise AttributeError, message
return wrapper …Run Code Online (Sandbox Code Playgroud) 我知道这可能听起来像一个愚蠢的问题,特别是对于那些了解python本质的人,但我只是想知道,有没有办法知道一个对象是否"实现了一个接口"以便说出来?
举一个我想说的例子:
假设我有这个功能:
def get_counts(sequence):
counts = {}
for x in sequence:
if x in counts:
counts[x] += 1
else:
counts[x] = 1
return counts
Run Code Online (Sandbox Code Playgroud)
我的问题是:有没有办法确保传递给函数的对象是iterable?我知道在Java或C#中我可以通过让方法接受任何实现特定接口的对象来实现这一点,让我们说(例如)iIterable像这样:void get_counts(iIterable sequence)
我的猜测是,在Python中,我必须采用抢占式内省检查(在一个decorator 或许?中)并exception在对象没有__iter__属性的情况下抛出自定义.但有更多的pythonic方式来做到这一点?