Python 方法调用本身而不使用方法名?
可以代替Python 方法调用本身而不使用方法名?,python,Python,可以代替self.M,比如self.\uu_u_u?因此,当函数名更改不会更改函数内部的代码时,函数中没有内置代码,但您可以使用一个decorator来完成此操作,该decorator确保在每次调用原始函数之前定义属性。您还需要保存和恢复属性,以防多个方法被类似地修饰,并且它们彼此调用 class C: def M: self.M() 请注意,self.\u FUNC.不是绑定方法,因为在构造类时会调用decorator。这意味着无论何时从修饰的方法中调用self,都必须将其作为第
self.M
,比如self.\uu_u_u
?因此,当函数名更改不会更改函数内部的代码时,函数中没有内置代码,但您可以使用一个decorator来完成此操作,该decorator确保在每次调用原始函数之前定义属性。您还需要保存和恢复属性,以防多个方法被类似地修饰,并且它们彼此调用
class C:
def M:
self.M()
请注意,self.\u FUNC.
不是绑定方法,因为在构造类时会调用decorator。这意味着无论何时从修饰的方法中调用self
,都必须将其作为第一个参数显式传递给该方法
更新
解决这个问题的一种方法是在第一次实际调用该方法之前不创建包装函数(然后保存它以减少将来的开销)。这将允许像调用任何其他方法一样调用它。我从题为的示例中得到了解决方案的想法
不,它不能,因为函数对象中的代码没有对自身的引用。我认为它实际上不是for@Zagorulkin:“可以代替
self.M
,比如self.\uu FUNC\uuu
?”对我来说似乎相对清晰——我也认为@Martijn的解释是类似的。
import functools
def decorator(func):
@functools.wraps(func)
def wrapper(self, *args, **kwargs):
save = getattr(self, '_FUNC_', None)
self._FUNC_ = func
retval = func(self, *args, **kwargs)
self._FUNC_ = save
if save: self._FUNC_ = save
else: delattr(self, '_FUNC_')
return retval
return wrapper
class C(object):
@decorator
def M(self, i):
if i > 0:
print i,
self._FUNC_(self, i-1) # explicit 'self' argument required
else:
print '- Blast Off!'
C().M(3) # -> 3 2 1 - Blast Off!
import functools
def decorator(f):
"""
Method decorator specific to the instance.
Uses a special descriptor to delay the definition of the method wrapper.
"""
class SpecialDescriptor(object):
def __init__(self, f):
self.f = f
def __get__(self, instance, cls):
if instance is None: # unbound method request?
return self.make_unbound(cls)
return self.make_bound(instance)
def make_unbound(self, cls):
@functools.wraps(self.f)
def wrapper(*args, **kwargs):
raise TypeError('unbound method {}() must be called with {} '
'instance as first argument'.format(
self.f.__name__,
cls.__name__))
return wrapper
def make_bound(self, instance):
@functools.wraps(self.f)
def wrapper(*args, **kwargs):
save = getattr(instance, '_FUNC_', None)
instance._FUNC_ = getattr(instance, self.f.__name__)
retval = self.f(instance, *args, **kwargs)
if save: instance._FUNC_ = save # restore any previous value
else: delattr(instance, '_FUNC_')
return retval
# instance no longer needs special descriptor, since method is now
# wrapped, so make it call the wrapper directly from now on
setattr(instance, self.f.__name__, wrapper)
return wrapper
return SpecialDescriptor(f)
class C(object):
@decorator
def M(self, i):
if i > 0:
print i,
self._FUNC_(i-1) # No explicit 'self' argument required
else:
print '- Blast Off!'
C().M(3) # -> 3 2 1 - Blast Off!