[英]Method call itself without method name?
class C:
def M:
self.M()
可以代替self.M
,像self.__FUNC__
嗎? 所以當函數名改變時不會改變函數內部的代碼
沒有內置任何東西,但是您可以使用裝飾器來確保在每次調用原始函數之前定義屬性。 您還需要保存和恢復屬性,以防多個方法被類似地裝飾並且它們相互調用。
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!
請注意, self._FUNC_
不是綁定方法,因為在構造類時會調用裝飾器。 這意味着無論何時從裝飾方法中調用self
必須將self
作為第一個參數顯式傳遞給方法。
更新
解決這個問題的一種方法是在第一次實際調用方法之前不創建包裝函數(然后保存它以減少未來的開銷)。 這將允許它像任何其他方法一樣被調用。 我從名為Class method decorator using instance的PythonDecoratorLibrary示例中得到了一個解決方案的想法。
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!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.