I have issues trying to implement an easy to use abstract factory.
Goal
To be able to define concrete factories this way :
class MyConcreteFactory( ... ):
@classmethod
def __load(cls, key):
obj = ... # Loading instructions here
return obj
To be able to use concretre factories this way
obj = MyConcreteFactory[key]
My attempt
I tried to define a metaclass for factories wich override bracket operator and encapsulate the factory pattern :
class __FactoryMeta(type):
__ressources = {}
@classmethod
def __getitem__(cls, key):
if key not in cls.__ressources:
cls.__ressources[key] = cls.__load(key)
return cls.__ressources[key]
@classmethod
def __load(cls, key):
raise NotImplementedError
class ConcreteFactory(metaclass=__FactoryMeta):
@classmethod
def __load(cls, key):
return "toto"
a = ConcreteFactory["mykey"]
print(a)
Issue
This failed because the __load method called is the one from the metaclass and not the one from the concrete class. The result is :
Traceback (most recent call last):
File "C:\Users\walter\workspace\Game\src\core\factories.py", line 34, in <module>
a = ConcreteFactory["mykey"]
File "C:\Users\walter\workspace\Game\src\core\factories.py", line 19, in __getitem__
cls.__ressources[key] = cls.__load(key)
File "C:\Users\walter\workspace\Game\src\core\factories.py", line 24, in __load
raise NotImplementedError
NotImplementedError
I tried to remove the __load method from the meta class but then i got this (predictable) error :
Traceback (most recent call last):
File "C:\Users\walter\workspace\Game\src\core\factories.py", line 30, in <module>
a = ConcreteFactory["mykey"]
File "C:\Users\walter\workspace\Game\src\core\factories.py", line 19, in __getitem__
cls.__ressources[key] = cls.__load(key)
AttributeError: type object '__FactoryMeta' has no attribute '_FactoryMeta__load'
Questions
Is there a way to access class method from a metaclass ? Am i wrong and should do this in an other way ? Then wich way ?
Aucun commentaire:
Enregistrer un commentaire