如何检查对象是否是方法定义?
How to check if an object is a method definition?
我想编写一个装饰器,它在获取函数或方法时做一些不同的事情。
例如,我想编写一个缓存装饰器,但如果它是一种方法,我不想将 self
作为键的一部分。
def cached(f):
def _internal(*args, **kwargs):
if ismethod(f):
key = create_key(*args[1:], **kwargs) # ignore self from args
else: # this is a regular function
key = create_key(*args, **kwargs)
return actual_cache_mechanism(key, f, *args, **kwargs)
return _internal
class A:
@cached
def b(self, something):
...
@cached
def c(something):
...
问题是调用@cached
时,无法区分方法和函数,因为它们都是function
类型。
那甚至可以做到吗?当我想到它时,我觉得实际上方法不知道它们在其中定义的上下文......
谢谢!
这是一种丑陋的 hack,但您可以使用 obj.__qualname__
查看 obj 是否在 class 中定义,方法是检查它是否有句点
if "." in obj.__qualname__":
#obj is a member of an object, so it is a method
不过我不确定它是否适合装饰器,因为要使其正常工作,需要在 class.
中定义该方法
我认为以良好的 pythonic 风格的名义避免这种内省装饰器是可取的。
您始终可以提取要缓存的函数以仅接受所需的参数:
@cached
def func(something):
return ...
class A:
def b(self, something):
self.bvalue = func(something)
对于评论中提到的情况(需要一个对象来获取结果,但它的值不影响它,例如socket),请参考这些问题:How to ignore a parameter in functools. lru_cache? and
我想编写一个装饰器,它在获取函数或方法时做一些不同的事情。
例如,我想编写一个缓存装饰器,但如果它是一种方法,我不想将 self
作为键的一部分。
def cached(f):
def _internal(*args, **kwargs):
if ismethod(f):
key = create_key(*args[1:], **kwargs) # ignore self from args
else: # this is a regular function
key = create_key(*args, **kwargs)
return actual_cache_mechanism(key, f, *args, **kwargs)
return _internal
class A:
@cached
def b(self, something):
...
@cached
def c(something):
...
问题是调用@cached
时,无法区分方法和函数,因为它们都是function
类型。
那甚至可以做到吗?当我想到它时,我觉得实际上方法不知道它们在其中定义的上下文......
谢谢!
这是一种丑陋的 hack,但您可以使用 obj.__qualname__
查看 obj 是否在 class 中定义,方法是检查它是否有句点
if "." in obj.__qualname__":
#obj is a member of an object, so it is a method
不过我不确定它是否适合装饰器,因为要使其正常工作,需要在 class.
中定义该方法我认为以良好的 pythonic 风格的名义避免这种内省装饰器是可取的。
您始终可以提取要缓存的函数以仅接受所需的参数:
@cached
def func(something):
return ...
class A:
def b(self, something):
self.bvalue = func(something)
对于评论中提到的情况(需要一个对象来获取结果,但它的值不影响它,例如socket),请参考这些问题:How to ignore a parameter in functools. lru_cache? and