# Interface

An interface, for an object, is a set of methods and attributes on that object.

In Python, we can use an abstract base class to define and enforce an interface.

### Using an Abstract Base Class

For example, say we want to use one of the abstract base classes from the `collections` module:

```
import collections
class MySet(collections.Set):
    pass
```

If we try to use it, we get an `TypeError` because the class we created does not support the expected behavior of sets:

```
>>> MySet()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class MySet with abstract methods
__contains__, __iter__, __len__
```

So we are required to implement at *least* `__contains__`, `__iter__`, and `__len__`. Let's use this implementation example from the [documentation](https://docs.python.org/2/library/collections.html#collections-abstract-base-classes):

```
class ListBasedSet(collections.Set):
    """Alternate set implementation favoring space over speed
    and not requiring the set elements to be hashable. 
    """
    def __init__(self, iterable):
        self.elements = lst = []
        for value in iterable:
            if value not in lst:
                lst.append(value)
    def __iter__(self):
        return iter(self.elements)
    def __contains__(self, value):
        return value in self.elements
    def __len__(self):
        return len(self.elements)

s1 = ListBasedSet('abcdef')
s2 = ListBasedSet('defghi')
overlap = s1 & s2
```

### Implementation: Creating an Abstract Base Class

We can create our own Abstract Base Class by setting the metaclass to `abc.ABCMeta` and using the `abc.abstractmethod` decorator on relevant methods. The metaclass will be add the decorated functions to the `__abstractmethods__` attribute, preventing instantiation until those are defined.

```
import abc
```

For example, "effable" is defined as something that can be expressed in words. Say we wanted to define an abstract base class that is effable, in Python 2:

```
class Effable(object):
    __metaclass__ = abc.ABCMeta
    @abc.abstractmethod
    def __str__(self):
        raise NotImplementedError('users must define __str__ to use this base class')
```

Or in Python 3, with the slight change in metaclass declaration:

```
class Effable(object, metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def __str__(self):
        raise NotImplementedError('users must define __str__ to use this base class')
```

Now if we try to create an effable object without implementing the interface:

```
class MyEffable(Effable): 
    pass
```

and attempt to instantiate it:

```
>>> MyEffable()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class MyEffable with abstract methods __str__
```

We are told that we haven't finished the job.

Now if we comply by providing the expected interface:

```
class MyEffable(Effable): 
    def __str__(self):
        return 'expressable!'
```

we are then able to use the concrete version of the class derived from the abstract one:

```
>>> me = MyEffable()
>>> print(me)
expressable!
```

There are other things we could do with this, like register virtual subclasses that already implement these interfaces, but I think that is beyond the scope of this question. The other methods demonstrated here would have to adapt this method using the `abc` module to do so, however.

### Conclusion

We have demonstrated that the creation of an Abstract Base Class defines interfaces for custom objects in Python.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://python-self-driving.gitbook.io/self-driving/python/interface.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
