gpt4 book ai didi

python - 如何循环定义三个方法?

转载 作者:太空狗 更新时间:2023-10-29 21:38:58 24 4
gpt4 key购买 nike

我有一个包含三个方法的抽象类,它们在某种意义上是等价的——它们都可以使用一些昂贵的转换函数相互定义。我希望能够编写一个派生类,它只需要覆盖其中一个方法并自动获取另外两个方法。示例

class FooBarBaz(object):
def foo(self, x):
return foo_from_bar(self.bar(x))
# OR return foo_from_baz(self.baz(x))

def bar(self, x):
return bar_from_foo(self.foo(x))
# OR return bar_from_baz(self.baz(x))

def baz(self, x):
return baz_from_bar(self.bar(x))
# OR return baz_from_foo(self.foo(x))

class Derived1(FooBarBaz):
def bar(self, x):
return 5
# at this point foo = foo_from_bar(5) and
# baz = baz_from_bar(5), which is what I wanted

class Derived2(FooBarBaz):
def foo(self, x):
return 6
# at this point bar = bar_from_foo(6) and
# baz = baz_from_bar(bar_from_foo(6)),
# which is not ideal, but still works

class Derived3(FooBarBaz):
def baz(self, x):
return 7
# at this point foo and bar remain defined
# in terms of each other, which is a PROBLEM

我知道我可以明确地告诉每个派生类要使用哪些转换。我想知道父类是否有办法在不修改子类的情况下自行解决这个问题。

最佳答案

您可以求助于元编程技术,例如编写一个自动填充剩余方法的元类,或者使用内省(introspection)依次查看 type(self).mro() 中的类以找出答案哪些方法已被覆盖。但是,这些选项对我来说完全属于“太神奇”的类别,所以我会选择更简单的选项。

简单地将每个方法分成两个:一个是通用的,一个是实际的实现。派生类覆盖实际实现:

class FooBarBaz(object):

def foo_impl(self, x):
raise NotImplementedError

def foo(self, x):
try:
return self.foo_impl(x)
except NotImplementedError:
try:
return foo_from_bar(self.bar_impl(x))
except NotImplementedError:
return foo_from_baz(self.baz_impl(x))

# Similarly fo bar and baz

class Dervied(FooBarBaz):

def bar_impl(self, x):
return 5

公共(public)逻辑也可以在装饰器中提取出来:

def first_implemented(func):
@functools.wraps
def wrapper(*args, **kwargs):
for f in func(*args, **kwargs):
try:
return f()
except NotImplementedError:
pass
raise NotImplementedError
return wrapper

class FooBarBaz(object):

def foo_impl(self, x):
raise NotImplementedError

@first_implemented
def foo(self, x):
yield lambda: self.foo_impl(x)
yield lambda: foo_from_bar(self.bar_impl(x))
yield lambda: foo_from_baz(self.baz_impl(x))

关于python - 如何循环定义三个方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40419097/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com