Python Cookbook 2Nd Edition Jun 1002005 [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Python Cookbook 2Nd Edition Jun 1002005 [Electronic resources] - نسخه متنی

David Ascher, Alex Martelli, Anna Ravenscroft

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید







Recipe 20.9. Checking Whether Interfaces Are Implemented


Credit: Raymond Hettinger


Problem


You want to ensure that the classes you define implement the
interfaces that they claim to implement.


Solution


Python does not have a formal concept of
"interface", but we can easily
represent interfaces by means of
"skeleton" classes such as:

class IMinimalMapping(object):
def _ _getitem_ _(self, key): pass
def _ _setitem_ _(self, key, value): pass
def _ _delitem_ _(self, key): pass
def _ _contains_ _(self, key): pass
import UserDict
class IFullMapping(IMinimalMapping, UserDict.DictMixin):
def keys(self): pass
class IMinimalSequence(object):
def _ _len_ _(self): pass
def _ _getitem_ _(self, index): pass
class ICallable(object):
def _ _call_ _(self, *args): pass

We follow the natural convention that any class can
represent an interface: the interface is the
set of methods and other attributes of the class. We can say that a
class C implements
an interface i if
C has all the methods and other attributes
of i (and, possibly, additional ones).

We can now define a simple custom metaclass that checks whether
classes implement all the interfaces they claim to implement:

# ensure we use the best available 'set' type with name 'set'
try:
set
except NameError:
from sets import Set as set
# a custom exception class that we raise to signal violations
class InterfaceOmission(TypeError):
pass
class MetaInterfaceChecker(type):
''' the interface-checking custom metaclass '''
def _ _init_ _(cls, classname, bases, classdict):
super(MetaInterfaceChecker, cls)._ _init_ _(classname, bases, classdict)
cls_defines = set(dir(cls))
for interface in cls._ _implements_ _:
itf_requires = set(dir(interface))
if not itf_requires.issubset(cls_defines):
raise InterfaceOmission, list(itf_requires - cls_defines)

Any class that uses MetaInterfaceChecker as its
metaclass must expose a class attribute _ _implements_
_
, an iterable whose items are the interfaces the class
claims to implement. The metaclass checks the claim, raising an
InterfaceOmission exception if the claim is false.


Discussion


Here's an example class using the
MetaInterfaceChecker custom metaclass:

class Skidoo(object):
''' a mapping which claims to contain all keys, each with a value
of 23; item setting and deletion are no-ops; you can also call
an instance with arbitrary positional args, result is 23. '''
_ _metaclass_ _ = MetaInterfaceChecker
_ _implements_ _ = IMinimalMapping, ICallable
def _ _getitem_ _(self, key): return 23
def _ _setitem_ _(self, key, value): pass
def _ _delitem_ _(self, key): pass
def _ _contains_ _(self, key): return True
def _ _call_ _(self, *args): return 23
sk = Skidoo( )

Any code dealing with an instance of such a class can choose to check
whether it can rely on certain interfaces:

def use(sk):
if IMinimalMapping in sk._ _implements_ _:
...code using 'sk[...]' and/or 'x in sk'...

You can, if you want, provide much fancier and more thorough checks,
for example by using functions from standard library module
inspect to check that the attributes being exposed
and required are methods with compatible signatures. However, this
simple recipe does show how to automate the simplest kind of checks
for interface compliance.


See Also


Library Reference and Python in a
Nutshell
docs about module sets, (in
Python 2.4 only) the set built-in, custom
metaclasses, the inspect module.


/ 394