书节上回
http://blog.chinaunix.net/uid-429659-id-3160023.html ,我们对twisted框架中的组件、接口和适配器的用法做阐述,
本章我们简要的对其中的例子中的适配器,用zope的组件实现以下。
从中可以大致了解zope组件对适配器的使用方式。
-
#! /usr/bin/env python
-
#coding=utf-8
-
-
from zope.interface import implements,Interface
-
from zope.component import adapts
-
from zope.component import getGlobalSiteManager, queryAdapter
-
-
class IAmericanSocket(Interface):
-
def voltage():
-
"""Return the voltage produced by this socket object, as an integer.
-
"""
-
-
class AmericanSocket:
-
implements(IAmericanSocket)
-
def voltage(self):
-
return 110
-
-
class ForeignSocket:
-
def voltage(self):
-
return 220
-
-
class AdaptToAmericanSocket:
-
implements(IAmericanSocket)
-
adapts(ForeignSocket)
-
def __init__(self, original):
-
"""
-
Pass the original ForeignSocket object as original
-
"""
-
self.original = original
-
def voltage(self):
-
return self.original.voltage() / 2
-
-
-
class HairDryer:
-
def plug(self, socket):
-
adapted = IAmericanSocket(socket)
-
assert adapted.voltage() == 110, "BOOM"
-
print "I was plugged in properly and am operating"
-
-
-
-
gsm = getGlobalSiteManager()
-
-
#注册适配器带有各个参数适配器
-
gsm.registerAdapter(AdaptToAmericanSocket, (ForeignSocket,), IAmericanSocket, "AAA")
-
-
#带有名称的简化方式
-
gsm.registerAdapter(AdaptToAmericanSocket, name='BBB')
-
-
#无名称适配器
-
gsm.registerAdapter(AdaptToAmericanSocket)
-
-
-
fs = ForeignSocket()
-
-
#查询适配器
-
print queryAdapter(fs, IAmericanSocket, 'AAA').voltage()
-
print queryAdapter(fs, IAmericanSocket, 'BBB').voltage()
-
-
#不带有名称的适配器可以利用接口来获取适配器
-
print IAmericanSocket(fs).voltage()
-
-
print IAmericanSocket.implementedBy(AmericanSocket) #True
-
print IAmericanSocket.implementedBy(ForeignSocket) #False
-
-
am = AmericanSocket()
-
-
print IAmericanSocket.providedBy(am) #True
-
print IAmericanSocket.providedBy(fs) #False
我们也把twisted的适配器实现方式的代码贴出来以下,易于对照掌握。
-
#适配器是一个将代码分化的非常有用的办法。
-
#但是如果没有一些基础设施的话也会有点问题。
-
#如果每一个想要使用适配器的代码都必须明确的构造一个它自己的适配器,元件之间的耦合会过分紧密。
-
#我们希望去实现松耦合,于是引入了twisted.python.components
-
#我们首先需要更具体的讨论接口。如我们之前提到的,接口只是以供用作标记的类。
-
#接口必须是 zope.interface.Interface 的子类,并且有一个对于 python 程序员来说奇怪的外观:
-
-
-
from zope.interface import Interface
-
from zope.interface import implements
-
from twisted.python import components
-
-
class IAmericanSocket(Interface):
-
def voltage():
-
"""Return the voltage produced by this socket object, as an integer.
-
"""
-
-
#它除了继承于 Interface 以外就像一个常规的类定义一般,只是没有没有任何方法实现的实体。
-
#因为既然 python 没有像 java 那样对接口的任何原生的语言级的支持,这样的做法可以区别接口和普通类的定义。
-
#现在我们有了一个定义好的接口,我们可以涉及这样使用的类:“实现了 IAmericanSocket 接口的 AmericanSocket 类”
-
#和“请给我一个使 ForeignSocket 适配 IAmericanSocket 的对象”。
-
#我们来看看如何声明一个类实现了一个接口:
-
class AmericanSocket:
-
implements(IAmericanSocket)
-
def voltage(self):
-
return 110
-
-
#声明一个类实现了一个接口,我们只需要简单的调用 zope.interface.implements 在类层次
-
#现在我们来实现 AdaptToAmericanSocket 类为一个真正的适配器。
-
#这里我们制定它实现了 IAmericanSocket:
-
class AdaptToAmericanSocket:
-
implements(IAmericanSocket)
-
def __init__(self, original):
-
"""
-
Pass the original ForeignSocket object as original
-
"""
-
self.original = original
-
def voltage(self):
-
return self.original.voltage() / 2
-
-
#到现在为止,我们并没有做什么,因此总是需要去定义更多类型。
-
#为了使元件更加有用,我们必须进行“元件注册”。
-
#既然 AdapterToAmericanSocket 实现了 IAmericanSocket 并且将 ForeignSocket 对象规范化了,
-
#我们可以注册 AdapterToAmericanSocket 作为 ForeignSocket 对 IAmericanSocket 的适配器。
-
#从代码可以更清晰的看到这一点:
-
class ForeignSocket:
-
def voltage(self):
-
return 220
-
-
#注册AdapterToAmericanSocket,
-
#作为ForeignSocket对IAmericanSocket的适配器
-
components.registerAdapter(
-
AdaptToAmericanSocket,
-
ForeignSocket,
-
IAmericanSocket)
-
-
#了解到如何使用元件,我们可以做的第一件事实确定一个对象是否实现了某一个接口:
-
print IAmericanSocket.implementedBy(AmericanSocket) #True
-
print IAmericanSocket.implementedBy(ForeignSocket) #False
-
-
am = AmericanSocket()
-
fs = ForeignSocket()
-
print IAmericanSocket.providedBy(am) #True
-
print IAmericanSocket.providedBy(fs) #False
-
-
#AmericanSocket 实体声明实现 IAmericanSocket
-
#但是 ForeignSocket没有,
-
#我们可以通过检查它是否实现了 IAmericanSocket 接口来指导是否是安全的
-
#如果我们要通过 ForeignSocket 来使用吹风机, 必须在使用前将它适配到 IAmericanSocket 接口。
-
-
class HairDryer:
-
def plug(self, socket):
-
adapted = IAmericanSocket(socket)
-
assert adapted.voltage() == 110, "BOOM"
-
print "I was plugged in properly and am operating"
-
-
HairDryer().plug(fs)
以上两个代码文件都可正常运行。
阅读(1571) | 评论(0) | 转发(0) |