<p>由于使用<code>ABCMeta</code>,因此必须定义抽象方法。可以从<code>__abstractmethods__</code>集中删除您的方法,但它是<code>frozenset</code>。不管怎样,它包括列出所有抽象方法。在</p>
<p>因此,您可以使用一个简单的描述符来代替<code>__getattr__</code>。在</p>
<p>例如:</p>
<pre><code>class Delegated(object):
def __init__(self, attrname=None):
self.attrname = attrname
def __get__(self, instance, owner):
if instance is None:
return self
delegatee = instance.delegatee
return getattr(delegatee, self.attrname)
class Delegator(DelegatorParent):
def __init__(self):
self.delegatee = ConcreteDelegatee()
DelegatorParent.__init__(self)
myMethod = Delegated('myMethod')
</code></pre>
<p>这里的一个优点是:开发人员拥有“myMethod”被委托的明确信息。在</p>
<p>如果您尝试:</p>
^{pr2}$
<p>它起作用了!但是,如果您忘记在<code>Delegator</code>类中实现<code>myMethod</code>,则会出现典型错误:</p>
<pre><code>Traceback (most recent call last):
File "script.py", line 40, in <module>
a = Delegator()
TypeError: Can't instantiate abstract class Delegator with abstract methods myMethod
</code></pre>
<p><strong>编辑</strong></p>
<p>这种实现可以概括如下:</p>
<pre><code>class DelegatorParent():
__metaclass__ = ABCMeta
@abstractmethod
def myMethod1(self):
pass
@abstractmethod
def myMethod2(self):
pass
def __init__(self):
self.a = 'whatever'
class ConcreteDelegatee1():
def myMethod1(self):
return 'myMethod1'
class ConcreteDelegatee2():
def myMethod2(self):
return 'myMethod2'
class DelegatedTo(object):
def __init__(self, attrname):
self.delegatee_name, self.attrname = attrname.split('.')
def __get__(self, instance, owner):
if instance is None:
return self
delegatee = getattr(instance, self.delegatee_name)
return getattr(delegatee, self.attrname)
class Delegator(DelegatorParent):
def __init__(self):
self.delegatee1 = ConcreteDelegatee1()
self.delegatee2 = ConcreteDelegatee2()
DelegatorParent.__init__(self)
myMethod1 = DelegatedTo('delegatee1.myMethod1')
myMethod2 = DelegatedTo('delegatee2.myMethod2')
a = Delegator()
result = a.myMethod2()
</code></pre>
<p>在这里,我们可以指定delegatee名称和delegatee方法。在</p>