0

I'm running python 2.7, 3.4 and 3.5. Only 2.7 raises a TypeError with the following code. I'm wondering if I'm doing something wrong, is this a know bug or is it something else?

from abc import ABCMeta, abstractmethod

class Base(object):
    __metaclass__ = ABCMeta

    @abstractmethod
    def bar(self):
        pass


class Concrete(Base):
    pass


confused = Concrete()

In Python 2.7 I get the following (helpful) error:

Traceback (most recent call last):
  File "confused.py", line 16, in <module>
    confused = Concrete()
TypeError: Can't instantiate abstract class Concrete with abstract methods bar

But in Python3.x it runs without an error (bad). Thanks.

AJP
  • 26,547
  • 23
  • 88
  • 127

2 Answers2

1

Declaring an abstract base class changed in python3 to:

import abc

class Base(metaclass=abc.ABCMeta):

    @abc.abstractmethod
    def bar(self):
        pass


class Concrete(Base):
    pass


Concrete() # Will raise a TypeError
Community
  • 1
  • 1
AJP
  • 26,547
  • 23
  • 88
  • 127
0

They behave differently in Python2.x and Python3.x .

Python3.6

# importing abstract base classes module
import abc

class GetterSetter(abc.ABC):
    '''
    ABSTRACT BASE CLASSES:

    -  An abstract base class is a kind of 'model' for other classes to be defined.
        - It is not designed to construct instances, but can be subclassed by regular classes

    - Abstract classes can define interface, or methods that must be implemented by its subclasses.

    '''


    # Abstract classes are not designed to be instantiated, only to be subclassed

    #  decorator for abstract class
    @abc.abstractmethod
    def set_val(self, input):
        """set the value in the instance"""
        return

    @abc.abstractmethod
    def get_val(self):
        """Get and return a value from the instance..."""
        return

# Inheriting from the above abstract class
class MyClass(GetterSetter):

    # methods overriding in the GetterSetter
    def set_val(self, input):
        self.val = input

    def get_val(self):
        return self.val


# Instantiate
x = MyClass()
print(x) # prints the instance <__main__.MyClass object at 0x10218ee48>
x = GetterSetter() #throws error, abstract classes can't be instantiated

Python2.x

import abc

class GetterSetter(object):
    # meta class is used to define other classes
    __metaclass__ = abc.ABCMeta


    #  decorator for abstract class
    @abc.abstractmethod
    def set_val(self, input):
        """set the value in the instance"""
        return

    @abc.abstractmethod
    def get_val(self):
        """Get and return a value from the instance..."""
        return

# Inheriting from the above abstract class
class MyClass(GetterSetter):

    # methods overriding in the GetterSetter
    def set_val(self, input):
        self.val = input

    def get_val(self):
        return self.val


# Instantiate
x = GetterSetter()
print(x)
x = GetterSetter() #throws error, abstract classes can't be instantiated

Check my answer here.

rzskhr
  • 931
  • 11
  • 10