Python Interface
When creating an application, it is important to continuously keep track of its changes. As an application grows, sometimes it gets hard to manage its updates and changes. Often, you see classes which look similar but are unrelated. This leads to confusion. In this situation, we use the python interface to deal with it. It helps us to determine which class we should use. Interfaces are a very important part of software engineering.
In this tutorial, we will learn about python interfaces and how we create an interface. Also, we will see how the interface in python differs from the interface of other languages.
An interface is like a blueprint of any class. At a high level, the design of a class can be represented with the help of an interface. Similar to class, interfaces are used to define methods, but the only difference is that the method defined using interfaces are abstract. An interface defines an abstract method which then gets implemented by the class, and then these classes implement interfaces.
The implementation of an interface in python is a bit different from the other languages like Java, C, C++, etc. In these languages, we have interface keywords, while python does not have any keywords like this. Implementing an interface in python is just another way of implementing abstraction by writing a set of code.
We have a package name zope.interface, which is used to implement the interface in python. This interface provides two objects which are interface and attribute directly. It provides some helper methods too.
How do we declare the interface in python?
In python, we declare an interface using a python class statement and a subclass of interface.Interface. This class is the parent interface of all interfaces.
The syntax for creating the interface
class Interface_name(zope.interface.Interface):
# methods and attributes
Example
import zope.interface
class Interface_name(zope.interface.Interface):
m = zope.interface.Attribute("foo")
def met1(self, m):
pass
def met2(self):
pass
print(type(Interface_name))
print(Interface_name.__module__)
print(Interface_name.__name__)
# get attribute
m = Interface_name['x']
print(m)
print(type(m))
Implementing interfaces in python
We use the implementer decorator in class to implement the interface in python. Once we implement a class, the class instances provide the interface.
The syntax for implementing an interface
@zope.interface.implementer(*interfaces)
class Class_name:
# methods
Example
import zope.interface
class Interface_name(zope.interface.Interface):
x1 = zope.interface.Attribute("foo")
def meth1(self, x1):
pass
def meth2(self):
pass
@zope.interface.implementer(Interface_name)
class Class_name:
def meth1(self, x1):
return x1**2
def meth2(self):
return "foo"
Methods used for implementing an interface
- implementedBy(class): It returns a boolean value (True or False). It gives true if the interface implements otherwise, false.
- providedBy(class): It returns the Boolean value false. Since the class does not provide an interface, it just implements it.
- list(zope.interface.implementedBy(class)): It returns the list of interfaces implemented by the class.
- list(zope.interface.providedBy(class)): It returns the list of interfaces provided by the class.
- providedBy(object): It returns a Boolean value. It returns true if the object provides the interface. Otherwise, false.
- list(zope.interface.providedBy(object)): It returns an empty list.
Example
import zope.interface
class Interface_name(zope.interface.Interface):
x = zope.interface.Attribute('foo')
def meth1(self, x, y, z):
pass
def meth2(self):
pass
@zope.interface.implementer(Interface_name)
class Class_name:
def meth1(self, x):
return x**2
def meth2(self):
return "foo"
obj_name = Class_name()
# asking an interface if it is implemented by the class
print(Interface_name.implementedBy(Class_name))
# Class_name does not provide Interface_name but implements it:
print(Interface_name.providedBy(Class_name))
# asking an interface if it is provided by an object:
print(MyInterface.providedBy(obj))
# asking what interfaces are implemented by a class:
print(list(zope.interface.implementedBy(Class_name)))
# asking what interfaces are provided by an object:
print(list(zope.interface.providedBy(obj_name)))
# class does not provide interface
print(list(zope.interface.providedBy(Class_name)))
Output
True
False
True
[<InterfaceClass __main__.Interface_name>]
[<InterfaceClass __main__.Interface_name>]
[]
Implementing interface inheritance
We can use one interface to implement other interfaces just by saving the interfaces in the list as the base interface.
Functions
- extends(interface) – Itreturns a boolean value, whether one interface extends another.
- isOrExtends(interface) – Itreturns a boolean value, whether interfaces are the same or one extends another.
- isEqualOrExtendedBy(interface) – It returns a boolean value, whether interfaces are same or another extends one.
Example
import zope.interface
class BaselistI(zope.interface.Interface):
def meth1(self, x):
pass
def meth2(self):
pass
class DerivedI(BaselistI):
def meth3(self, x, y):
pass
@zope.interface.implementer(DerivedI)
class class_name:
def meth1(self, z):
return z**3
def meth2(self):
return 'foo'
def meth3(self, x, y):
return x ^ y
# Get base interfaces
print(DerivedI.__bases__)
# Asking whether baseI inherits DerivedI
print(BaselistI.extends(DerivedI))
# Ask whether baselistI is equal to or is extended by DerivedI
print(BaselistI.isEqualOrExtendedBy(DerivedI))
# Ask whether baselistI is equal to or extends DerivedI
print(BaselistI.isOrExtends(DerivedI))
# Ask whether DerivedI is equal to or extends BaselistI
print(DerivedI.isOrExtends(DerivedI))
Output
(<InterfaceClass __main__.BaselistI>, )
False
True
False
True