python @abstractmethod decorator

PythonAbcAbstract Methods

Python Problem Overview


I have read python docs about abstract base classes:

From here: > abc.abstractmethod(function) > A decorator indicating abstract methods. > > Using this decorator requires that the class’s metaclass is ABCMeta or > is derived from it. A class that has a metaclass derived from ABCMeta > cannot be instantiated unless all of its abstract methods and > properties are overridden.

And here

> You can apply the @abstractmethod decorator to methods such as draw() > that must be implemented; Python will then raise an exception for > classes that don’t define the method. Note that the exception is only > raised when you actually try to create an instance of a subclass > lacking the method.

I've used this code to test that out:

import abc

class AbstractClass(object):
  __metaclass__ = abc.ABCMeta
  
  @abc.abstractmethod
  def abstractMethod(self):
    return

class ConcreteClass(AbstractClass):
  def __init__(self):
    self.me = "me"

c = ConcreteClass()
c.abstractMethod()

The code goes fine, so I don't get it. If I type c.abstractMethod I get:

<bound method ConcreteClass.abstractMethod of <__main__.ConcreteClass object at 0x7f694da1c3d0>>

What I'm missing here? ConcreteClass must implement the abstract methods, but I get no exception.

Python Solutions


Solution 1 - Python

Are you using python3 to run that code? If yes, you should know that declaring metaclass in python3 have changes you should do it like this instead:

import abc

class AbstractClass(metaclass=abc.ABCMeta):

  @abc.abstractmethod
  def abstractMethod(self):
      return

The full code and the explanation behind the answer is:

import abc

class AbstractClass(metaclass=abc.ABCMeta):

	@abc.abstractmethod
	def abstractMethod(self):
		return

class ConcreteClass(AbstractClass):

	def __init__(self):
		self.me = "me"

# Will get a TypeError without the following two lines:
# 	def abstractMethod(self):
# 		return 0

c = ConcreteClass()
c.abstractMethod()

If abstractMethod is not defined for ConcreteClass, the following exception will be raised when running the above code: TypeError: Can't instantiate abstract class ConcreteClass with abstract methods abstractMethod

Solution 2 - Python

Import ABC from abc and make your own abstract class a child of ABC can help make the code look cleaner.

from abc import ABC, abstractmethod

class AbstractClass(ABC):

  @abstractmethod
  def abstractMethod(self):
    return

class ConcreteClass(AbstractClass):
  def __init__(self):
    self.me = "me"

# The following would raise a TypeError complaining 
# abstractMethod is not implemented
c = ConcreteClass()  

Tested with Python 3.6

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSebastianView Question on Stackoverflow
Solution 1 - PythonmouadView Answer on Stackoverflow
Solution 2 - Pythonl001dView Answer on Stackoverflow