什么是检查一个类是否定义了函数的最快方法?
我正在写一个AI状态空间searchalgorithm,我有一个通用的类,可以用来快速实现一个searchalgorithm。 一个子类将定义必要的操作,而algorithm则完成剩下的操作。
这里是我卡住的地方:我想要避免一次又一次地重新生成父状态,所以我有以下函数,它返回可以合法应用于任何状态的操作:
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函数默认会抛出。
有没有更快的方法来检查是否没有定义函数捕获exception?
我正在想办法检查目前的目录,但这似乎并不正确。 hasattr通过调用getattr并检查是否引发来实现,这不是我想要的。
是的,使用getattr()
来获取属性,并使用callable()
来validation它是一个方法:
invert_op = getattr(self, "invert_op", None) if callable(invert_op): invert_op(self.path.parent_op)
请注意,当属性不存在时, getattr()
通常会抛出exception。 但是,如果您指定一个默认值(在这种情况下为None
),则会返回该值。
它适用于Python 2和Python 3
hasattr(connection, 'invert_opt')
如果连接对象具有定义的函数invert_opt
则hasattr
返回True
。 这是您要放牧的文件
https://docs.python.org/2/library/functions.html#hasattr https://docs.python.org/3/library/functions.html#hasattr
有没有更快的方法来检查是否没有定义函数捕获exception?
你为什么反对? 在大多数Pythonic案件中,最好是要求宽恕而不是允许。 😉
hasattr通过调用getattr并检查是否引发来实现,这不是我想要的。
同样,为什么呢? 以下是Pythonic:
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)
基本上也是通过捕获exception来实现的。 在Python的土地上没有任何错误!
我喜欢Nathan Ostgard的回答,我投了赞成票。 但另一种解决问题的方法是使用memoizing装饰器,它将caching函数调用的结果。 所以,你可以继续,并有一个昂贵的function,计算出一些东西,但是当你打电话过来,后来的电话很快; 该函数的memoized版本在字典中查找参数,从实际函数计算结果时在dict中查找结果,并立即返回结果。
这是Raymond Hettinger的一个名为“lru_cache”的装饰器的配方。 这个版本现在在Python 3.2的functools模块中是标准的。
http://code.activestate.com/recipes/498245-lru-and-lfu-cache-decorators/
就像Python中的任何东西一样,如果你努力的努力,你可以在胆量上做一些非常讨厌的事情。 现在,这是讨厌的部分:
def invert_op(self, op): raise NotImplementedError def is_invert_op_implemented(self): # Only works in CPython 2.x of course return self.invert_op.__code__.co_code == 't\x00\x00\x82\x01\x00d\x00\x00S'
请帮我们一个忙,就是继续做你自己的问题,除非你是PyPy团队的黑客入侵Python解释器,否则不要使用它。 Pythonic有什么,我在这里是纯EVIL 。
这里的响应检查string是否是对象属性的名称。 需要额外的步骤(使用可调用的)来检查属性是否是一个方法。
所以它归结为:什么是最快的方式来检查对象obj是否有一个属性attrib。 答案是
'attrib' in obj.__dict__
这是因为一个字典散列它的密钥,所以检查密钥的存在是很快的。
请参阅下面的时间比较。
>>> class SomeClass(): ... pass ... >>> obj = SomeClass() >>> >>> getattr(obj, "invert_op", None) >>> >>> %timeit getattr(obj, "invert_op", None) 1000000 loops, best of 3: 723 ns per loop >>> %timeit hasattr(obj, "invert_op") The slowest run took 4.60 times longer than the fastest. This could mean that an intermediate result is being cached. 1000000 loops, best of 3: 674 ns per loop >>> %timeit "invert_op" in obj.__dict__ The slowest run took 12.19 times longer than the fastest. This could mean that an intermediate result is being cached. 10000000 loops, best of 3: 176 ns per loop