回答此问题可获得 20 贡献值,回答如果被采纳可获得 50 分。
<p><a href="https://docs.python.org/2/reference/datamodel.html#new-style-special-lookup" rel="nofollow noreferrer">python documentation</a>表示在查找特殊方法时可以绕过<code>__getattribute__</code>。这是通过语言语法或内置函数进行隐式调用的结果。你知道吗</p>
<p>例如</p>
<pre><code>elem = container[0]
</code></pre>
<p>不同于:</p>
<pre><code>elem = container.__getattribute__('__getitem__')[0]
</code></pre>
<p>下面是另一个例子:</p>
<pre><code>class WrappedList:
def __init__(self):
object.__setattr__(self, 'interal_list', ['apple', 'pear', 'orange'])
def __getattribute__(self, attr_name):
interal_list = object.__getattribute__(self, 'interal_list')
attr = getattr(interal_list, attr_name)
return attr
wl = WrappedList()
print("\nSTART TEST 01 ------------------------")
try:
print(wl[0]) # throws TypeError: 'WrappedList' object does not support indexing
except TypeError as e:
print(e)
print("\nSTART TEST 02 ------------------------")
try:
getitem = getattr(wl, '__getitem__')
print(getitem(0)) # works just fine
except TypeError as e:
print(e)
</code></pre>
<p>我想编写一个名为<code>MagicOverrider</code>的类,其中任何从<code>MagicOverrider</code><strong>继承的类总是调用<code>__getattribute__</code>,而不是绕过它。我的问题是我们怎么做?你知道吗</p>
<p>我尝试了以下方法:</p>
<pre><code>class MagicOverrider:
def __call__(self, *args, **kwargs):
f = getattr(self, '__call__')
return f(*args, **kwargs)
def __iter__(self, *args, **kwargs):
f = getattr(self, '__iter__')
return f(*args, **kwargs)
def __getitem__(self, *args, **kwargs):
f = getattr(self, '__getitem__')
return f(*args, **kwargs)
def __setitem__(self, *args, **kwargs):
f = getattr(self, '__setitem__')
return f(*args, **kwargs)
def __add__(self, *args, **kwargs):
f = getattr(self, '__add__')
return f(*args, **kwargs)
def __sub__(self, *args, **kwargs):
f = getattr(self, '__sub__')
return f(*args, **kwargs)
def __mul__(self, *args, **kwargs):
f = getattr(self, '__mul__')
return f(*args, **kwargs)
def __truediv__(self, *args, **kwargs):
f = getattr(self, '__truediv__')
return f(*args, **kwargs)
def __floordiv__(self, *args, **kwargs):
f = getattr(self, '__floordiv__')
return f(*args, **kwargs)
def __mod__(self, *args, **kwargs):
f = getattr(self, '__mod__')
return f(*args, **kwargs)
def __divmod__(self, *args, **kwargs):
f = getattr(self, '__divmod__')
return f(*args, **kwargs)
def __pow__(self, *args, **kwargs):
f = getattr(self, '__pow__')
return f(*args, **kwargs)
def __lshift__(self, *args, **kwargs):
f = getattr(self, '__lshift__')
return f(*args, **kwargs)
def __rshift__(self, *args, **kwargs):
f = getattr(self, '__rshift__')
return f(*args, **kwargs)
def __and__(self, *args, **kwargs):
f = getattr(self, '__and__')
return f(*args, **kwargs)
def __xor__(self, *args, **kwargs):
f = getattr(self, '__xor__')
return f(*args, **kwargs)
def __or__(self, *args, **kwargs):
f = getattr(self, '__or__')
return f(*args, **kwargs)
def __radd__(self, *args, **kwargs):
f = getattr(self, '__radd__')
return f(*args, **kwargs)
def __rsub__(self, *args, **kwargs):
f = getattr(self, '__rsub__')
return f(*args, **kwargs)
def __rmul__(self, *args, **kwargs):
f = getattr(self, '__rmul__')
return f(*args, **kwargs)
def __rtruediv__(self, *args, **kwargs):
f = getattr(self, '__rtruediv__')
return f(*args, **kwargs)
def __rfloordiv__(self, *args, **kwargs):
f = getattr(self, '__rfloordiv__')
return f(*args, **kwargs)
def __rmod__(self, *args, **kwargs):
f = getattr(self, '__rmod__')
return f(*args, **kwargs)
def __rdivmod__(self, *args, **kwargs):
f = getattr(self, '__rdivmod__')
return f(*args, **kwargs)
def __rpow__(self, *args, **kwargs):
f = getattr(self, '__rpow__')
return f(*args, **kwargs)
def __rlshift__(self, *args, **kwargs):
f = getattr(self, '__rlshift__')
return f(*args, **kwargs)
def __rrshift__(self, *args, **kwargs):
f = getattr(self, '__rrshift__')
return f(*args, **kwargs)
def __rand__(self, *args, **kwargs):
f = getattr(self, '__rand__')
return f(*args, **kwargs)
def __rxor__(self, *args, **kwargs):
f = getattr(self, '__rxor__')
return f(*args, **kwargs)
def __neg__(self, *args, **kwargs):
f = getattr(self, '__neg__')
return f(*args, **kwargs)
def __pos__(self, *args, **kwargs):
f = getattr(self, '__pos__')
return f(*args, **kwargs)
def __abs__(self, *args, **kwargs):
f = getattr(self, '__abs__')
return f(*args, **kwargs)
def __invert__(self, *args, **kwargs):
f = getattr(self, '__invert__')
return f(*args, **kwargs)
def __complex__(self, *args, **kwargs):
f = getattr(self, '__complex__')
return f(*args, **kwargs)
def __int__(self, *args, **kwargs):
f = getattr(self, '__int__')
return f(*args, **kwargs)
def __float__(self, *args, **kwargs):
f = getattr(self, '__float__')
return f(*args, **kwargs)
def __round__(self, *args, **kwargs):
f = getattr(self, '__round__')
return f(*args, **kwargs)
def __index__(self, *args, **kwargs):
f = getattr(self, '__index__')
return f(*args, **kwargs)
def __eq__(self, *args, **kwargs):
f = getattr(self, '__eq__')
return f(*args, **kwargs)
def __ne__(self, *args, **kwargs):
f = getattr(self, '__ne__')
return f(*args, **kwargs)
def __lt__(self, *args, **kwargs):
f = getattr(self, '__lt__')
return f(*args, **kwargs)
def __le__(self, *args, **kwargs):
f = getattr(self, '__le__')
return f(*args, **kwargs)
def __gt__(self, *args, **kwargs):
f = getattr(self, '__gt__')
return f(*args, **kwargs)
def __ge__(self, *args, **kwargs):
f = getattr(self, '__ge__')
return f(*args, **kwargs)
def __bool__(self, *args, **kwargs):
f = getattr(self, '__bool__')
return f(*args, **kwargs)
def __new__(self, *args, **kwargs):
f = getattr(self, '__new__')
return f(*args, **kwargs)
def __del__(self, *args, **kwargs):
f = getattr(self, '__del__')
return f(*args, **kwargs)
def __slots__(self, *args, **kwargs):
f = getattr(self, '__slots__')
return f(*args, **kwargs)
def __hash__(self, *args, **kwargs):
f = getattr(self, '__hash__')
return f(*args, **kwargs)
def __instancecheck__(self, *args, **kwargs):
f = getattr(self, '__instancecheck__')
return f(*args, **kwargs)
def __subclasscheck__(self, *args, **kwargs):
f = getattr(self, '__subclasscheck__')
return f(*args, **kwargs)
def __subclasshook__(self, *args, **kwargs):
f = getattr(self, '__subclasshook__')
return f(*args, **kwargs)
def __ror__(self, *args, **kwargs):
f = getattr(self, '__ror__')
return f(*args, **kwargs)
def __iadd__(self, *args, **kwargs):
f = getattr(self, '__iadd__')
return f(*args, **kwargs)
def __isub__(self, *args, **kwargs):
f = getattr(self, '__isub__')
return f(*args, **kwargs)
def __imul__(self, *args, **kwargs):
f = getattr(self, '__imul__')
return f(*args, **kwargs)
def __itruediv__(self, *args, **kwargs):
f = getattr(self, '__itruediv__')
return f(*args, **kwargs)
def __ifloordiv__(self, *args, **kwargs):
f = getattr(self, '__ifloordiv__')
return f(*args, **kwargs)
def __imod__(self, *args, **kwargs):
f = getattr(self, '__imod__')
return f(*args, **kwargs)
def __ipow__(self, *args, **kwargs):
f = getattr(self, '__ipow__')
return f(*args, **kwargs)
def __ilshift__(self, *args, **kwargs):
f = getattr(self, '__ilshift__')
return f(*args, **kwargs)
def __irshift__(self, *args, **kwargs):
f = getattr(self, '__irshift__')
return f(*args, **kwargs)
def __iand__(self, *args, **kwargs):
f = getattr(self, '__iand__')
return f(*args, **kwargs)
def __ixor__(self, *args, **kwargs):
f = getattr(self, '__ixor__')
return f(*args, **kwargs)
def __repr__(self, *args, **kwargs):
f = getattr(self, '__repr__')
return f(*args, **kwargs)
def __str__(self, *args, **kwargs):
f = getattr(self, '__str__')
return f(*args, **kwargs)
def __cmp__(self, *args, **kwargs):
f = getattr(self, '__cmp__')
return f(*args, **kwargs)
def __rcmp__(self, *args, **kwargs):
f = getattr(self, '__rcmp__')
return f(*args, **kwargs)
def __nonzero__(self, *args, **kwargs):
f = getattr(self, '__nonzero__')
return f(*args, **kwargs)
def __unicode__(self, *args, **kwargs):
f = getattr(self, '__unicode__')
return f(*args, **kwargs)
</code></pre>
<p>但是,我的解决方案至少有两个问题:</p>
<ul>
<li>如果在python的未来版本中引入新的魔术方法,它将不再工作</li>
<li>第一行<code>class MagicOverrider:</code>抛出<code>TypeError: 'function' object is not iterable</code></li>
</ul>