在python中委托@classmethods
我需要一个委托类来委托在python中委托@classmethods,python,delegation,Python,Delegation,我需要一个委托类来委托@classmethod。以下是我尝试过的: class Foo(object): def __init__(self, a): self.a = a @classmethod def from_a(cls, a): return cls(a) class Bar(object): def __init__(self, foo): elf._foo = foo def __ge
@classmethod
。以下是我尝试过的:
class Foo(object):
def __init__(self, a):
self.a = a
@classmethod
def from_a(cls, a):
return cls(a)
class Bar(object):
def __init__(self, foo):
elf._foo = foo
def __getattribute__(self, name):
return getattr(self._foo, name)
但是,这当然没有定义如何查找
Foo
(不是Foo
)的属性,因此Bar.from_a(5)
将引发AttributeError
。当然,通过在Bar
上定义一个from\u a
方法,或者通过调用Bar(Foo.from\u a(5))
在实例化时,可以显式地做到这一点,但我宁愿隐式地做到这一点。想法?我开始研究一种简单的方法,即使用元类,但实际上相当复杂。您可能应该在这里做的是从Foo
继承Bar
,但我还是会向您展示我的想法:
import types
import functools
def make_delegating_type(delegatee):
class DelegatingType(type):
def __getattr__(self, name):
obj = getattr(delegatee, name)
if isinstance(obj, (types.FunctionType, types.MethodType)):
@functools.wraps(obj)
def wrapper(*args, **kwargs):
result = obj(*args, **kwargs)
if isinstance(result, delegatee):
return self(result)
return result
return wrapper
return obj
return DelegatingType
class Foo(object):
def __init__(self, a): self.a = a
@classmethod
def from_a(cls, a): return cls(a)
class Bar(object):
__metaclass__ = make_delegating_type(Foo)
def __init__(self, foo): self._foo = foo
def __getattr__(self, name): return getattr(self._foo, name)
请注意,在3.x中,您将使用类栏(object,metaclass=make\u delegating\u type(Foo)
,而不是栏顶部的元类=make\u delegating\u type(Foo)
行
这是如何工作的。您当前的版本当前将Bar
实例上的属性查找委托给Foo
实例,这使用了一个元类,以便类Bar
上的属性查找也委托给类Foo
。不幸的是,这并不像只使用\tattr\uuuu
返回的定义getattr(delegatee,name)
,因为如果a查找的属性是一个工厂函数,如示例中所示,则需要该工厂函数的一个版本,该函数将返回委托类型的实例。因此,例如Bar.from\u a(5)
应与Bar(Foo.from\u a(5))相同
,使用这种简单的方法,您只需从_a(5)
中获得Foo.这就是为什么所有逻辑都会检测属性是否是函数或方法,并创建一个包装器来检查该函数/方法的返回类型
再次重申,我不建议您使用此代码!它比仅从Bar
上定义,或从Bar
继承Foo
要复杂得多。但希望这对您来说是一次学习经历,就像对我一样。Foo的Foo
实例满足了该类要求hod.你想实现什么?为什么?显然from_a
不存在于Bar
上,因为你没有定义它或子类Foo
。你为什么期望它呢?@MartijnPieters:但提问者正在寻找使Bar.from_a(5)
work,所以看不到Foo
的实例。@SteveJessop:啊,我明白你的意思。然后你需要一个元类。@Martijn:我也在想元类,但我也在想,总的来说,提问者可能不需要元类,而需要做一些更有意义的事情。我仍在想为什么Bar
不仅仅继承自Foo
。Bar
在这种情况下不能继承自Foo
。它需要是委托类或代理类。请检查注释。