gpt4 book ai didi

带有元类的 Python 工厂模式实现

转载 作者:太空宇宙 更新时间:2023-11-04 05:32:19 26 4
gpt4 key购买 nike

我在尝试实现易于使用的抽象工厂时遇到问题。

目标

为了能够以这种方式定义具体工厂:

class MyConcreteFactory( ... ):
@classmethod
def __load(cls, key):
obj = ... # Loading instructions here
return obj

能够以这种方式使用混凝土工厂

obj = MyConcreteFactory[key]

我的尝试

我尝试为覆盖括号运算符并封装工厂模式的工厂定义元类:

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)

问题

这失败了,因为调用的 __load 方法是元类中的方法而不是具体类中的方法。结果是:

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

我试图从元类中删除 __load 方法,但后来我得到了这个(可预测的)错误:

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'

问题

有没有办法从元类访问类方法?我错了吗,应该以其他方式做到这一点?那怎么走呢?

解决方案

class __FactoryMeta(type):

ressources = {}

def __getitem__(cls, key):
if key not in cls.ressources:
cls.ressources[key] = cls.load(key)
return cls.ressources[key]

def load(cls, key):
raise NotImplementedError


class ConcreteFactory(metaclass=__FactoryMeta):

@classmethod
def load(cls, key):
return "toto"


a = ConcreteFactory["mykey"]
print(a)

最佳答案

你不应该在元类中使用@classmethod。元类的实例是类本身,因此:

def __getitem__(cls, key):

实际上是类并且:

@classmethod
def __getitem__(metacls, key):

获取元类作为第一个参数。

无论哪种情况,我相信元类都会使这个问题变得更加复杂。我相信更可行的方法是创建一个基工厂类,相应地对其进行子类化,并将子类的实例用作工厂。

关于带有元类的 Python 工厂模式实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36728138/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com