假设我有以下代码,它接受一个距离函数和两个点,并吐出距离:
def distance(dist_fun, p1, p2):
## SOME ASSERTION HERE on dist_fun ##
## Suppose, just for this post, we've already checked p1 and p2 are
## n-tuples of integers.
assert (len(p1) == len(p2)), "Coordinates are different dimensions."
dist = dist_fun(p1, p2)
assert (dist>=0), "Negative distance is not possible."
return dist
def euclid(p1, p2): #as an example dist function.
return pow(reduce(lambda x,y: x+y, [pow((p1[i] - p2[i]), 2) for i in range(len(p1))]),0.5)
我希望能够检查用户是否使用特定的距离函数,首先是实际上是函数。在此之后,我可以查看其他内容,但我的主要问题是:我如何断言dist_fun实际上是一个函数?
如果没有简单的方法可以做到这一点,或者有其他办法可以做到这一点,请告诉我。我以前在Python中做过一些测试,但直到现在才遇到过这个问题。我已经看到函数的“类型”是“函数”,但是Python不允许我将它用作类型?除了这里之外,回去尝试会更容易吗?
答案 0 :(得分:5)
Python的座右铭当然是,请求宽恕而不是许可更好。所以,你完全可以指望用户传递有效的输入,或except
TypeError
如果你试图调用无法调用的东西而被抛出的assert (callable(dist_fun))
。
那就是说,如果你真的想断言某事是一个功能,我想你总能检查一下这个类型......
{{1}}
答案 1 :(得分:1)
我怎么断言dist_fun实际上是一个函数?
通常通过以下方式完成:
if callable(f):
...
答案 2 :(得分:1)
如果你想断言它实际上是一个函数,那很容易:
assert ininstance(dist_fun, types.FunctionType)
......或:
assert inspect.isfunction(dist_fun)
一般来说,遇到这个问题时:
我已经看到函数的“类型”是“函数”,但Python不允许我将它用作类型?
...对于内置类型,types
中提供了您想要的类型和/或可以在inspect
中找到更简单检查的函数。
然而,你可能不想这样做;相反,你想断言它是可以调用的东西。毕竟,绑定方法,functools.partial
,具有自定义__call__
方法的对象,在C扩展中实现的自定义函数类对象等都在这里同样有用,对吧?所以使用callable
:
assert callable(dist_fun)
(除非您需要支持Python 3.0-3.1,或者非常古老的1.x版本。callable
在1.4左右添加,在3.0中删除,然后在3.2中添加。)
或者,甚至更好(仅限Python 3.3+):
assert inspect.signature(dist_fun).bind(p1, p2)
这会检查它不仅可以调用,而且可以使用要传递它的参数调用。 (当它只是两个位置参数时,这不是什么大问题......但是当你传递关键字参数,或者使用 / *等转发args时,它可以是。)
答案 3 :(得分:0)
if callable(dist_fun):
# do whatever you wanna do
或
assert callable(dist_func)