Implement an Interface¶
There are several ways to indicate that instances of a class provide an interface. These are listed here, and for performance reasons, should typically be considered in the order that they appear.
Register a class that implements the interface¶
To indicate that a class implements an interface, decorate the class with
jute.implements
.
@jute.implements(BufferedWritable)
class OutputWriter:
def write(self, buf):
sys.stdout.write(buf)
def flush(self):
sys.stdout.flush()
If it is not possible to decorate the class, use the interface’s
register_implementation
method to specify a class as an implementation of the
interface.
BufferedWritable.register_implementation(file)
Dynamically indicate that an instance provides the interface¶
Sometimes, especially for wrapper classes, it is useful to declare support for
an interface dynamically. Dynamic implementations are declared using the
jute.DynamicInterface
interface, which provides a single method provides_interface
:
@jute.implements(jute.DynamicInterface)
class PrintAttributeAccessWrapper:
def __init__(self, wrapped):
self.wrapped = wrapped
def __getattr__(self, name):
# return the wrapped object's attributes
print('Accessing attribute {}'.format(name))
return getattr(self.wrapped, name)
def provides_interface(self, interface):
# Check wrapped object's support for interface.
return interface.provided_by(self.wrapped)
Note, this object may print “Accessing attribute write” more than expected.
Interface verification uses getattr
to verify implementation of the interface.
This may be an issue if __getattr__
performs non-trivial work to resolve the
attribute.