Chinaunix首页 | 论坛 | 博客
  • 博客访问: 5120009
  • 博文数量: 921
  • 博客积分: 16037
  • 博客等级: 上将
  • 技术积分: 8469
  • 用 户 组: 普通用户
  • 注册时间: 2006-04-05 02:08
文章分类

全部博文(921)

文章存档

2020年(1)

2019年(3)

2018年(3)

2017年(6)

2016年(47)

2015年(72)

2014年(25)

2013年(72)

2012年(125)

2011年(182)

2010年(42)

2009年(14)

2008年(85)

2007年(89)

2006年(155)

分类: Python/Ruby

2013-12-18 16:58:35

书节上回 http://blog.chinaunix.net/uid-429659-id-3160023.html ,我们对twisted框架中的组件、接口和适配器的用法做阐述,

本章我们简要的对其中的例子中的适配器,用zope的组件实现以下。

从中可以大致了解zope组件对适配器的使用方式。


  1. #! /usr/bin/env python
  2. #coding=utf-8

  3. from zope.interface import implements,Interface
  4. from zope.component import adapts
  5. from zope.component import getGlobalSiteManager, queryAdapter

  6. class IAmericanSocket(Interface):
  7.     def voltage():
  8.         """Return the voltage produced by this socket object, as an integer.
  9.         """
  10.         
  11. class AmericanSocket:
  12.     implements(IAmericanSocket)
  13.     def voltage(self):
  14.         return 110
  15.     
  16. class ForeignSocket:
  17.     def voltage(self):
  18.         return 220

  19. class AdaptToAmericanSocket:
  20.     implements(IAmericanSocket)
  21.     adapts(ForeignSocket)
  22.     def __init__(self, original):
  23.         """
  24.         Pass the original ForeignSocket object as original
  25.         """
  26.         self.original = original
  27.     def voltage(self):
  28.         return self.original.voltage() / 2
  29.     

  30. class HairDryer:
  31.     def plug(self, socket):
  32.         adapted = IAmericanSocket(socket)
  33.         assert adapted.voltage() == 110, "BOOM"
  34.         print "I was plugged in properly and am operating"
  35.         


  36. gsm = getGlobalSiteManager()

  37. #注册适配器带有各个参数适配器
  38. gsm.registerAdapter(AdaptToAmericanSocket, (ForeignSocket,), IAmericanSocket, "AAA")

  39. #带有名称的简化方式
  40. gsm.registerAdapter(AdaptToAmericanSocket, name='BBB')

  41. #无名称适配器
  42. gsm.registerAdapter(AdaptToAmericanSocket)


  43. fs = ForeignSocket()

  44. #查询适配器
  45. print queryAdapter(fs, IAmericanSocket, 'AAA').voltage()
  46. print queryAdapter(fs, IAmericanSocket, 'BBB').voltage()

  47. #不带有名称的适配器可以利用接口来获取适配器
  48. print IAmericanSocket(fs).voltage()

  49. print IAmericanSocket.implementedBy(AmericanSocket) #True
  50. print IAmericanSocket.implementedBy(ForeignSocket) #False

  51. am = AmericanSocket()

  52. print IAmericanSocket.providedBy(am) #True
  53. print IAmericanSocket.providedBy(fs) #False

我们也把twisted的适配器实现方式的代码贴出来以下,易于对照掌握。


  1. #适配器是一个将代码分化的非常有用的办法。
  2. #但是如果没有一些基础设施的话也会有点问题。
  3. #如果每一个想要使用适配器的代码都必须明确的构造一个它自己的适配器,元件之间的耦合会过分紧密。
  4. #我们希望去实现松耦合,于是引入了twisted.python.components
  5. #我们首先需要更具体的讨论接口。如我们之前提到的,接口只是以供用作标记的类。
  6. #接口必须是 zope.interface.Interface 的子类,并且有一个对于 python 程序员来说奇怪的外观:


  7. from zope.interface import Interface
  8. from zope.interface import implements
  9. from twisted.python import components

  10. class IAmericanSocket(Interface):
  11.     def voltage():
  12.         """Return the voltage produced by this socket object, as an integer.
  13.         """

  14. #它除了继承于 Interface 以外就像一个常规的类定义一般,只是没有没有任何方法实现的实体。
  15. #因为既然 python 没有像 java 那样对接口的任何原生的语言级的支持,这样的做法可以区别接口和普通类的定义。
  16. #现在我们有了一个定义好的接口,我们可以涉及这样使用的类:“实现了 IAmericanSocket 接口的 AmericanSocket 类”
  17. #和“请给我一个使 ForeignSocket 适配 IAmericanSocket 的对象”。
  18. #我们来看看如何声明一个类实现了一个接口:
  19. class AmericanSocket:
  20.     implements(IAmericanSocket)
  21.     def voltage(self):
  22.         return 110
  23.     
  24. #声明一个类实现了一个接口,我们只需要简单的调用 zope.interface.implements 在类层次
  25. #现在我们来实现 AdaptToAmericanSocket 类为一个真正的适配器。
  26. #这里我们制定它实现了 IAmericanSocket:
  27. class AdaptToAmericanSocket:
  28.     implements(IAmericanSocket)
  29.     def __init__(self, original):
  30.         """
  31.         Pass the original ForeignSocket object as original
  32.         """
  33.         self.original = original
  34.     def voltage(self):
  35.         return self.original.voltage() / 2
  36.     
  37. #到现在为止,我们并没有做什么,因此总是需要去定义更多类型。
  38. #为了使元件更加有用,我们必须进行“元件注册”。
  39. #既然 AdapterToAmericanSocket 实现了 IAmericanSocket 并且将 ForeignSocket 对象规范化了,
  40. #我们可以注册 AdapterToAmericanSocket 作为 ForeignSocket 对 IAmericanSocket 的适配器。
  41. #从代码可以更清晰的看到这一点:
  42. class ForeignSocket:
  43.     def voltage(self):
  44.         return 220

  45. #注册AdapterToAmericanSocket,
  46. #作为ForeignSocket对IAmericanSocket的适配器
  47. components.registerAdapter(
  48.     AdaptToAmericanSocket,
  49.     ForeignSocket,
  50.     IAmericanSocket)

  51. #了解到如何使用元件,我们可以做的第一件事实确定一个对象是否实现了某一个接口:
  52. print IAmericanSocket.implementedBy(AmericanSocket) #True
  53. print IAmericanSocket.implementedBy(ForeignSocket) #False

  54. am = AmericanSocket()
  55. fs = ForeignSocket()
  56. print IAmericanSocket.providedBy(am) #True
  57. print IAmericanSocket.providedBy(fs) #False

  58. #AmericanSocket 实体声明实现 IAmericanSocket
  59. #但是 ForeignSocket没有,
  60. #我们可以通过检查它是否实现了 IAmericanSocket 接口来指导是否是安全的
  61. #如果我们要通过 ForeignSocket 来使用吹风机, 必须在使用前将它适配到 IAmericanSocket 接口。

  62. class HairDryer:
  63.     def plug(self, socket):
  64.         adapted = IAmericanSocket(socket)
  65.         assert adapted.voltage() == 110, "BOOM"
  66.         print "I was plugged in properly and am operating"
  67.         
  68. HairDryer().plug(fs)

以上两个代码文件都可正常运行。




阅读(1593) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~