Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/344.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何表示类对特定组的归属:基类还是特征属性?_Python - Fatal编程技术网

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

Python 如何表示类对特定组的归属:基类还是特征属性?,python,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 =

在静态类型语言中,为了解决下面的问题,我将使用接口(或抽象类等)。但我想知道在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\u value()
方法。当然,这个想法是用户可以实现它

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

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

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

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

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

我强烈建议使用

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


关于不要与具有
get\u value()
函数的其他对象混淆,Python习惯用法假定编码者是负责人,不会试图破坏他实现代码的系统,因此一个
hasattr(obj,“get\u value”)
就足够了。如果类有
.get\u value()
则可以假定它是一个值提供程序而不是一个值(否则,该值就是值本身。
.get\u value()
对一个值,返回
self
是毫无用处的)。

使用
try
-
除了中的
之外Python@ssm在此特定上下文中,try-except不起作用(或者我不知道怎么做).事实上,正如您所想象的,值提供程序是延迟值生成器。这意味着,实际上我想存储值提供程序。如果我得到单个值,我将创建一些标准值提供程序,它总是返回给定的值。这样,我将确定,存储在我的对象中的是值提供程序,并且我不必每次测试它ime我使用它。@DmitrySemikin
try
-
除外
有效:
def是\u值\u提供程序(x):try:x.get\u值;返回True,但属性除外错误:返回False
。总之,您称之为“检查特征属性”这似乎正是duck键入的意思,这是python中通常使用的方式。@Bakuriu啊,好吧,的确。我没有首先想到。但是如果
get\u value
是长操作呢?执行
x.get\u value
不会执行任何操作,因此无论
get\u value
是什么,它只是查找att事实上,这个代码相当于调用名为“get\u value”的
hasattr
。谢谢你的回答。我同意。注意:可能是这样的,值提供程序本身返回的“value”可能有“get\u value”类似的问题也出现了,当人们试图通过检查
len()
的可用性来区分集合和单个对象时,但随后得到字符串集合。。。