[英]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()
類裝飾器或classProvides
或moduleProvides
函數來獲得相同的結果。
在這種情況下,您想要的是工廠定義; 類是工廠,當被調用時,生成一個實例,因此工廠接口必須提供__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.