首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >zope.interface的继承参数(由vs isinstance提供)

zope.interface的继承参数(由vs isinstance提供)
EN

Software Engineering用户
提问于 2014-06-15 11:12:35
回答 1查看 683关注 0票数 4

通过zope.interface解决的抽象基类,接口的继承有哪些限制?

在Jeff在2010年给出的关于接口的后续谈话中,在11:50,Jeff认为使用由您提供的,是没有继承层次结构的。为什么这很重要?

如果我想使用一个接口并从另一个基类继承行为,Python会给我多个继承的机会。我知道应该避免多重继承,而组合设计被认为是另一种选择,但在这种情况下,我并不是从abc继承行为,而是一个接口,所以在行为意义上,我并不是真正的多重继承。

我不明白继承的论点..。

提前感谢你分享你的见解。

编辑,更新视频链接:通过回车机

EN

回答 1

Software Engineering用户

回答已采纳

发布于 2016-12-14 07:41:19

这段视频在2016年12月似乎还没有发布,但我同意你的观点,即接口继承没有实现继承那么麻烦。例如,请参见https://softwareengineering.stackexchange.com/a/260354

然而,zope.interface“提供者”关系将我们从继承层次结构中解放出来的一种感觉是,它允许对象提供接口,即使它们的类没有提供接口。https://docs.zope.org/zope.interface/README.html#declaring-provided-interfaces展示了直接提供接口的对象的示例,尽管它们各自的类没有提供接口。

例如,如果IWriter接口需要writeflush方法,那么定义顶级writeflush函数(并调用zope.interface.moduleProvides(IWriter))的模块提供了该接口,尽管模块一般不需要。

这也是Zope接口方法不将self命名为参数的原因-- self是类实例方法特有的实现细节。

对于包装另一个对象并动态映射其方法的对象,单个对象提供接口的能力变得特别有用。

例如,假设我们有:

代码语言:javascript
复制
class IWriter(zope.interface.Interface):
    def write(s):
        """Write stuff"""
    def flush():
        """Flush stuff"""

class TextWriter:
    zope.interface.implements(IWriter)
    def write(self, s):
        ...
    def flush(self):
        ...

tw = TextWriter()

do_something(tw)

如果我们看到tw输出有时不被刷新的问题,我们可以使用TextWriter方法来显示调试信息(例如log(timestamp, caller, methodname))。但是,生成timestampcaller信息的代码很复杂,需要在多个地方添加。现在,每个TextWriter实例都将显示调试信息。

相反,我们可以将感兴趣的特定TextWriter封装在一个记录其方法调用的包装器对象中。

代码语言:javascript
复制
class DebugWrapper:

    def __init__(self, wrapped):
        self._wrapped = wrapped

    def __getattr__(self, name):
        ... # generate timestamp and caller
        log(timestamp, caller, name)
        return getattr(self._wrapped, name)

dtw = DebugWrapper(tw)

do_something(dtw)

注意,DebugWrapper是泛型的。它可以包裹任何物体。它可以从一个单独的库导入。它独立于IWriter接口,这很好,因为我们可以更容易地在其他地方重用它。

但是,如果do_something函数希望接收接口IWriter的提供程序,那么我们现在遇到的问题是,dtw满足接口语法,但没有“正式”提供接口。

这是一个重要的区别。

接口不只是定义语法签名。它们还定义了语法的语义意义。通过接口,我们可以指定提供相同方法的两个对象是否实际上提供相同的语义。这与Python常用的鸭子类型有很大的不同,因为相同的语法意味着相同的语义。

无论如何,我们问题的解决方案是通知每个人,dtw对象确实提供了IWriter接口,尽管它的类DebugWrapper没有提供。

代码语言:javascript
复制
zope.interface.directlyProvides(dtw, IWriter)
票数 3
EN
页面原文内容由Software Engineering提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://softwareengineering.stackexchange.com/questions/245068

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档