如何表示类对特定组的归属:基类还是特征属性?

2024-09-30 22:20:59 发布

您现在位置:Python中文网/ 问答频道 /正文

在静态类型语言中,为了解决下面的问题,我将使用接口(或抽象类等)。但我想知道在python中是否有更“pythonic”的方法

因此,请考虑以下情况:

class MyClass(object):
    # ...
    def my_function(self, value_or_value_provider):
        if is_value_provider(value_or_value_provider):
            self._value_provider = value_or_value_provider
        else:
            self._value_provider = StandardValueProvider(value_or_valie_provider)
            # `StandardValueProvider` just always returns the same value.

上面的“值提供者”是定制类,它有get_value()方法。当然,这个想法是用户可以实现的

现在,问题是:实现is_value_provider()的最佳方式是什么?即,区分“单一价值”和“价值提供者”的最佳方式是什么

我想到的第一个想法是使用继承:引入带有空实现的基类BaseValueProvider,并在文档中告知自定义“值提供者”必须从中继承。然后在is_value_provider()函数中检查isinstance(objectToCheck, BaseValueProvider)。我不喜欢这个解决方案的一点是,在这种情况下(特别是在python的情况下),继承似乎是多余的,因为我们甚至不能强迫一个派生实现get_value()方法的人。此外,对于想要实现定制“值提供者”的人来说,这个解决方案意味着需要对模块有依赖性,该模块公开了BaseValueProvider

另一种解决方案是使用“trait-attribute”。也就是说,不用检查基类,而是用hasattr()函数检查特定属性的存在性。我们可以检查get_value()方法本身是否存在。或者,如果我们担心方法的名称太常见,我们可以检查专用的trait属性,比如is_my_library_value_provider。然后在文档中告诉我们,任何定制的“值提供者”不仅必须有get_value()方法,而且还必须有is_my_library_value_provider。第二种解决方案似乎更好,因为它不滥用继承,并且允许实现定制的“值提供者”,而不依赖于提供基类的其他库

有人能评论一下哪种解决方案更可取(或者如果有其他更好的解决方案),为什么

编辑:稍微更改示例以反映这样一个事实,即值提供者将在以后存储和使用(可能多次)


Tags: or方法selfgetisvaluemy方式
1条回答
网友
1楼 · 发布于 2024-09-30 22:20:59

我强烈建议使用^{}

您的代码将具有很高的可读性,通过ducktyping您可以稍后使其与您所想到的其他类型一起工作

为了避免与其他具有get_value()函数的对象混淆,Python习惯用法假定编码者是负责人,不会试图破坏他实现代码的系统,因此一个hasattr(obj, "get_value")就足够了。如果类具有.get_value(),则可以假定它是值提供者而不是值(否则,值就是值本身)^{<在值上,返回self是非常无用的)

相关问题 更多 >