I try to implement an interface in Python 3.6 (I know they don't exist in Python). Using the following minimal example:
import time
class ModuleInterface:
# How often the module information is updated (int in seconds).
interval = None
def update(self):
raise NotImplementedError
class HardDisk(ModuleInterface):
###############################################################################
pass # First
###############################################################################
# def update(self): # Second
# time.sleep(self.interval) # Second
###############################################################################
hd = HardDisk()
hd.update()
The code should yield a NotImplementedError for the first case. In the second case I would like to get a similar error but I don't know how to implement this correctly in Python. The idea of an interface is to yield an error if something is not defined. But interval is defined, which is why the second case will yield a TypeError. This is however not the kind of error I'd like to get. It would be perfect to assert for all members of the ModuleInterface that they must be defined by the inheriting class.
You are looking for the abc
module. Exemple (Python 2.7 - you'll find py3 exemples in the 3.6 doc):
import abc
import time
class ModuleInterface(object):
__metaclass__ = abc.ABCMeta
# How often the module information is updated (int in seconds).
interval = abc.abstractproperty()
@abc.abstractmethod
def update(self):
""" must be implemented """
class WrongHardDisk(ModuleInterface):
""" This one doesn't define `interval`
so it cannot be instanciated
"""
def update(self):
time.sleep(self.interval)
class HardDisk(ModuleInterface):
interval = 5
def update(self):
time.sleep(self.interval)
try:
# Will raise a TypeError
whd = WrongHardDisk()
except Exception as e:
print type(e), e
# this one will work as expected
hd = HardDisk()
hd.update()
AFAICT the only modification to make it work with Python 3.6 should be to replace this (untested):
class ModuleInterface(object):
__metaclass__ = abc.ABCMeta
# ...
with
class ModuleInterface(metaclass=abc.ABCMeta):
# ...