from abc import ABCMeta, abstractmethod
class DynamicAbstractMeta(ABCMeta):
def __new__(cls, name, bases, namespace):
item_attributes = ["person", "animal"]
# Create abstract methods based on Item attributes
for attribute in item_attributes:
namespace[attribute] = abstractmethod(lambda x, a=attribute: None)
return super().__new__(cls, name, bases, namespace)
class A(metaclass=DynamicAbstractMeta):
pass
class Item(A):
def person(self):
print("person")
def animal(self):
print("animal")
item_instance = Item()
item_instance.person()
item_instance.animal()
trackback:
item_instance = Item() TypeError: Can't instantiate abstract class Item with abstract methods animal, person
Why does it still throw an error even though I implemented the abstract methods in the Item class? Please help me.
Executes correctly without any errors.
The problem is that Item
inherits A
, so it also has the same metaclass of DynamicAbstractMeta
, whose __new__
method would overwrite the person
and animal
methods defined in Item
with abstract methods, making Item
an abstract class.
You can add a check in DynamicAbstractMeta.__new__
so that if the method is called for a subclass, identified by checking if any of the base classes has the same metaclass, it would not add any abstract methods to the namespace:
class DynamicAbstractMeta(ABCMeta):
def __new__(cls, name, bases, namespace):
if cls not in map(type, bases): # add this check
item_attributes = ["person", "animal"]
for attribute in item_attributes:
namespace[attribute] = abstractmethod(lambda x, a=attribute: None)
return super().__new__(cls, name, bases, namespace)