在一个独立的python应用程序中,我使用zope.interface、zope.component包注册和访问应用程序的适配器。我想我可以使用元类概念从元类的init方法中注册适配器。这将“自动化”适配器的注册过程。您认为这种方法存在问题吗,例如使用zope包添加到类中的属性?提前感谢您的投入。
from zope import component
from zope.interface import Interface, implements
class MetaclassAdapter(type):
def __init__(cls, clsname, bases, attrs):
super(MetaclassAdapter, cls).__init__(clsname, bases, attrs)
component.provideAdapter(cls, cls.__component_adapts__, cls.__implements_advice_data__[0][0])
class IDocument(Interface):
"""Document interface."""
def title():
pass
def author():
pass
def content():
pass
class IPrinter(Interface):
"""Printer interface."""
def write():
"""Print instance to ..."""
class Printer(object):
"""Adapt instances that provide IDocument interface to IPrinter.
Print document's attributes to stdout.
"""
__metaclass__ = MetaclassAdapter
implements(IPrinter)
component.adapts(IDocument)
def __init__(self, context):
"""Store adapted instance that provides IDocument."""
self.context = context
def write(self):
"""Serialize document."""
print 'author: ', self.context.author()
print 'title: ', self.context.title()
print 'content: ', self.context.content()
class TextDocument(object):
implements(IDocument)
def __init__(self, author, title, content):
self._author = author
self._title = title
self._content = content
def title(self):
return self._title
def author(self):
return self._author
def content(self):
return self._content
# Create instance of TextDocument and store / serialize it to...
IPrinter(TextDocument("Leo T.", "Short Stories", "Once upon a time...")).write()发布于 2011-02-22 23:42:54
仅仅因为你能,并不意味着你应该。
注册适配器是类之外的一行代码,所以我只需要这样做,而不是将行为放在元类中。外显好于内隐。
发布于 2011-02-22 23:16:56
编辑:接受@Tobu的建议,不要这么做。我在下面的回答是不正确的,但为了完整起见留在了原地。这是不正确的,因为zope.interface.implements元类洗牌还没有处理接口信息。
我认为这种做法肯定是明智的。您不需要将提供的接口或经过调整的规范传递给provideAdapter,只要实现了一个接口,注册方法就会计算出这些接口:
class MetaclassAdapter(type):
def __init__(cls, clsname, bases, attrs):
super(MetaclassAdapter, cls).__init__(clsname, bases, attrs)
component.provideAdapter(cls)如果您想支持实现多个接口的类(通过直接声明或继承),那么您必须想出语义来确定选择哪个接口作为适配器目标接口。
在这种情况下,只需通过registerAdapter关键字参数将所选接口交给provides=。我建议您使用zope.interface自省API (zope.interfaces.implementedBy)来查找提供的接口,而不是直接从类的内部数据结构中获取它们。
https://stackoverflow.com/questions/5083506
复制相似问题