簡體   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