检查一个类是否定义了函数的最快方法是什么?
我正在写一个人工智能状态空间搜索算法,创建了一个通用的类,可以快速实现搜索算法。子类会定义必要的操作,而算法会处理其他的事情。
我现在遇到问题了:我想避免一次又一次地重新生成父状态,所以我有一个函数,它可以返回对任何状态合法的操作:
def get_operations(self, include_parent=True):
ops = self._get_operations()
if not include_parent and self.path.parent_op:
try:
parent_inverse = self.invert_op(self.path.parent_op)
ops.remove(parent_inverse)
except NotImplementedError:
pass
return ops
而invert_op函数默认是会抛出异常的。
有没有比捕获异常更快的方法来检查这个函数是否未定义呢?
我在想可以检查一下是否在目录中存在,但这似乎不太对。hasattr是通过调用getattr来实现的,然后再检查是否抛出异常,这不是我想要的。
8 个回答
22
有没有比捕获异常更快的方法来检查一个函数是否未定义?
你为什么反对这样做呢?在大多数情况下,Python 编程中,宁可先尝试再说,也就是“先犯错再请求原谅”。;-)
hasattr 是通过调用 getattr 并检查是否抛出异常来实现的,这正是我不想要的。
那你为什么会这样想呢?下面的做法其实很符合 Python 的风格:
try:
invert_op = self.invert_op
except AttributeError:
pass
else:
parent_inverse = invert_op(self.path.parent_op)
ops.remove(parent_inverse)
或者,
# if you supply the optional `default` parameter, no exception is thrown
invert_op = getattr(self, 'invert_op', None)
if invert_op is not None:
parent_inverse = invert_op(self.path.parent_op)
ops.remove(parent_inverse)
不过要注意,getattr(obj, attr, default)
基本上也是通过捕获异常来实现的。在 Python 的世界里,这没有什么问题!
77
这个在Python 2和Python 3中都能用
hasattr(connection, 'invert_opt') and callable(connection.invert_opt)
hasattr
这个函数会返回True
,如果连接对象里有一个叫invert_opt
的属性。callable
则是用来检查这个属性是否可以被调用(比如说,它是不是一个函数)。这里有一些文档链接,供你参考:
309
没错,可以用 getattr()
来获取一个属性,然后用 callable()
来检查它是不是一个方法:
invert_op = getattr(self, "invert_op", None)
if callable(invert_op):
invert_op(self.path.parent_op)
需要注意的是,通常情况下,如果你用 getattr()
去获取一个不存在的属性,它会报错。不过,如果你给它指定一个默认值(在这里是 None
),那么它就会返回这个默认值,而不会报错。