1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
|
# (C) Copyright 2005-2023 Enthought, Inc., Austin, TX
# All rights reserved.
#
# This software is provided without warranty under the terms of the BSD
# license included in LICENSE.txt and may be redistributed only under
# the conditions described in the aforementioned license. The license
# is also available online at http://www.enthought.com/licenses/BSD.txt
#
# Thanks for using Enthought open source!
# --(Interfaces)---------------------------------------------------------------
"""
Interfaces
==========
In Traits 3.0, the ability to define, implement and use *interfaces* has been
added to the package.
Defining Interfaces
-------------------
Interfaces are defined by subclassing from the **Interface** class, as shown
in the example below::
from traits.api import Interface
class IName(Interface):
def get_name(self):
" Returns the name of an object. "
This same code is shown in the **IName Interface** tab of the code.
Interface classes are intended mainly as documentation of the methods and
traits that the interface defines, and should not contain any actual
implementation code, although no check is performed to enforce this currently.
Implementing Interfaces
-----------------------
A class declares that it implements one or more interfaces using the
**provides** decorator, which has the form::
@provides(interface [, interface2, ..., interfacen])
The decorator declares that the decorated class implements each of the
*interfaces* specified as an argument to **provides**. For example::
from traits.api import HasTraits, provides
@provides(IName)
class Person(HasTraits):
def get_name(self):
...
Note that in the current version, traits does not check to ensure that the
class decorated with **provides** actually implements the interfaces
it says it does.
Using Interfaces
----------------
Being able to define and implement interfaces would be of little use without
the ability to *use* interfaces in your code. In traits, using an interface is
accomplished using the **Instance** trait, as shown in the following example::
from traits.api import HasTraits, Instance
class Apartment(HasTraits):
renter = Instance(IName)
Using an interface class in an **Instance** trait definition declares that the
trait only accepts values which implement the specified interface.
As before, the **Instance** trait can also be used with classes that are not
interfaces, such as::
from traits.api import HasTraits, Instance
class Apartment(HasTraits):
renter = Instance(Person)
In this case, the value of the trait must be an object which is an instance of
the specified class or one of its subclasses.
"""
# --<Imports>------------------------------------------------------------------
from traits.api import HasTraits, Instance, Interface, provides, Str
# --[IName Interface]----------------------------------------------------------
# Define the 'IName' interface:
class IName(Interface):
def get_name(self):
""" Returns the name of an object. """
# --[Person Class]-------------------------------------------------------------
@provides(IName)
class Person(HasTraits):
first_name = Str("John")
last_name = Str("Doe")
# Implementation of the 'IName' interface:
def get_name(self):
""" Returns the name of an object. """
return "%s %s" % (self.first_name, self.last_name)
# --[Apartment Class]----------------------------------------------------------
# Define a class using an object that implements the 'IName' interface:
class Apartment(HasTraits):
renter = Instance(IName)
# --[Example*]-----------------------------------------------------------------
# Create an object implementing the 'IName' interface:
william = Person(first_name="William", last_name="Adams")
# Create an apartment, and assign 'renter' an object implementing 'IName':
apt = Apartment(renter=william)
# Verify that the object works correctly:
print("Renter is:", apt.renter.get_name())
|