I have written a Python script and just found out that Python 3.4 does not restrict an abstract class from being instantiated while Python 2.7.8 did.
Here is my abstract class in the file named Shape.py
.
from abc import ABCMeta, abstractmethod
class Shape:
__metaclass__ = ABCMeta # Making the class abstract
def __init__(self):
pass:
@abstractmethod
def getArea(self):
print("You shouldn't have called me.")
return None
Now I created another class that inherits from the abstract
class Shape
:
Filename: Circle.py
from Shape import Shape
class Circle(Shape):
PI = 3.141
def __init__(self, radius=0):
self.radius = radius
def getArea(self): # Overriding it from Shape class
return self.PI * self.radius ** 2
Now in my Main.py
:
from Shape import Shape
from Circle import Circle
shape = Shape() # This gave me errors in Python 2.7.8 but not in Python 3.4
shape2 = Circle(5)
print("Area of shape = "+str(shape.getArea())) # This should have not been executed.
print("Area of circle = "+str(shape2.getArea()))
This Main.py
gives errors on commented areas in Python2.7.8 but works fine on Python3.4.
Output on Python3.4:
You shouldn't have called me
Area of shape = None
Area of circle = 78.525
In Python 3, you declare a metaclass differently:
class Shape(metaclass=ABCMeta):
See the Customizing class creation documentation:
The class creation process can be customised by passing the
metaclass
keyword argument in the class definition line, or by inheriting from an existing class that included such an argument.
All examples in the abc
module documentation for Python 3 also use the correct notation.
This was changed to give metaclasses a chance to get involved with class creation earlier than was possible in Python 2; see PEP 3115.
The __metaclass__
attribute has no special meaning anymore, so you didn't actually create a proper abstract class.
Demo with Python 3.4:
>>> from abc import ABCMeta, abstractmethod
>>> class Shape(metaclass=ABCMeta):
... @abstractmethod
... def getArea(self):
... print("You shouldn't have called me.")
... return None
...
>>> Shape()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class Shape with abstract methods getArea
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With