繁体   English   中英

zope.interface可以定义类'__init__方法应该如何看?

[英]Can zope.interface define how a class' __init__ method should look?

我有几个类似的类,它们都将由相同的代码初始化,因此需要具有相同的“构造函数签名”。 (在动态Python中是否真的有构造函数和签名?我离题了。)

使用zope.interface定义类__init __参数的最佳方法是什么?

我将粘贴一些我用于试验zope.interface的代码以方便讨论:


from zope.interface import Interface, Attribute, implements, verify

class ITest(Interface):
    required_attribute = Attribute(
        """A required attribute for classes implementing this interface.""")
    def required_method():
        """A required method for classes implementing this interface."""

class Test(object):
    implements(ITest)
    required_attribute = None
    def required_method():
        pass

print verify.verifyObject(ITest, Test())
print verify.verifyClass(ITest, Test)

我不能只在ITest中定义一个__ init __函数,因为它将由Python解释器专门处理 - 我想? 无论如何,它似乎都不起作用。 那么,使用zope.interface定义“类构造函数”的最佳方法是什么?

首先: 提供实现接口的概念之间存在很大差异。

基本上,类实现了一个接口,这些类的实例提供了该接口。 毕竟,类是实例的蓝图,详细说明了它们的实现。

现在,接口描述了实例提供的实现,但__init__方法不是实例的一部分! 它是由类直接提供的接口的一部分(Python术语中的类方法)。 如果你要定义一个__init__界面中的任何方法,你宣布你的实例都( 提供 )一个__init__方法,以及 (作为一个实例方法)。

所以接口描述了你得到的实例,而不是你如何得到它们。

现在,接口不仅可用于描述实例提供的功能。 您还可以在Python中使用任何类型对象的接口,包括模块和类。 您必须使用directlyProvides方法为这些方法分配接口,因为您不会调用它们来创建实例。 您还可以在类或模块声明中使用@provider()类装饰器或classProvidesmoduleProvides函数来获得相同的结果。

在这种情况下,您想要的是工厂定义; 类是工厂,当被调用时,生成一个实例,因此工厂接口必须提供__call__方法来指示它们是可调用的。 以下是使用工厂界面设置的示例:

from zope import interface

class ITest(interface.Interface):
    required_attribute = interface.Attribute(
        """A required attribute for classes implementing this interface.""")
    def required_method():
        """A required method for classes implementing this interface."""

class ITestFactory(interface.Interface):
    """Creates objects providing the ITest interface"""
    def __call__(a, b):
        """Takes two parameters"""

@interface.implementer(ITest)
@interface.provider(ITestFactory)
class Test(object):
    def __init__(self, a, b):
        self.required_attribute = a*b

    def required_method():
        return self.required_attribute

zope.component为工厂提供了一个便利类和接口 ,添加了一个getInterfaces方法和一个标题和描述,使发现和内省更容易一些。 然后,您可以将IFactory接口子类IFactory更好地记录__init__参数:

from zope import component

class ITestFactory(component.interfaces.IFactory):
    """Creates objects providing the ITest interface"""
    def __call__(a, b):
        """Takes two parameters"""

testFactory = component.Factory(Test, 'ITest Factory', ITestFactory.__doc__)
interface.directlyProvides(testFactory, ITestFactory)

您现在可以将该工厂注册为zope.component实用程序,例如,允许其他代码查找所有ITestFactory提供程序。

我在这里使用zope.interface.directlyProvides来标记带有子类ITestFactory接口的工厂实例,因为zope.component.Factory实例通常只提供IFactory接口。

不, __init__的处理方式不同:

from zope.interface import Interface, Attribute, implements, verify

class ITest(Interface):
    required_attribute = Attribute(
        """A required attribute for classes implementing this interface.""")
    def __init__(a,b):
        """Takes two parameters"""
    def required_method():
        """A required method for classes implementing this interface."""

class Test(object):
    implements(ITest)
    def __init__(self, a, b):
        self.required_attribute = a*b
    def required_method():
        return self.required_attribute

print verify.verifyClass(ITest, Test)
print verify.verifyObject(ITest, Test(2,3))

我不是100%肯定你在问什么。 如果你想在Python中的几个类上使用相同的构造函数签名,唯一的方法是在这些类上实际具有相同的构造函数签名。 :-)如果你通过子类化或通过为每个类具有不同的__init__来执行此操作并不重要,只要它们具有相同的签名即可。

zope.interface不是关于定义方法,而是声明签名。 因此,您可以在__init__上定义具有特定签名的接口,但这只是说“此对象实现了签名IMyFace”,但是说类实现接口实际上不会使类实现接口。 你仍然需要实现它。

你问的是没有多大意义。 接口文件应该保留接口描述,但不能在任何时候从某些地方调用任何特定的实现。 你要做什么才能继承。 来自一个共同的基类。 zope.interface不是关于继承。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM