微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Python工厂动态实例化

如何解决Python工厂动态实例化

我是C#程序员,并且我希望建立一个简单的工厂。遵守豁免规定:

class ShapeFactory:
    _registry: Dict[ShapeType,Shape] = {
        ShapeType.Shape: lambda: Shape(),ShapeType.Circle: lambda: Circle(),ShapeType.Square: lambda: Square()
    }

    def Create(self,key: ShapeType) -> Shape:
        if key in self._registry:
            return self._registry.get(key)
        raise KeyError(key)

    def Register(self,key: ShapeType,value: Shape) -> None:
        if key not in self._registry:
            self._registry[key] = value
        raise KeyError(type)

问题在于Create将始终返回Circle的相同实例。如何在允许OCP的同时实现一种动态实例化对象的方法

编辑: 进一步说明我的观点;在C#中,我将我的字典声明为:

Dictionary<ShapeType,Func<Shape>> _registry = new Dictionary{
    [ShapeType.Shape] = () => new Shape(),[ShapeType.Circle] = () => new Circle(),[ShapeType.Square] = () => new Square()
}

这将始终为字典的每个值返回一个新实例化的对象。这是我希望在python中重现的效果

解决方法

您在设计中遇到了一些较大的问题。

首先,如果您在类中具有可变属性,则应在类的_registry方法(与实例隔离)中定义__init__

接下来,_registry的type属性错误。您有dict的{​​{1}},而不是lambda的实例。您需要ShapeDict[ShapeType,Callable[[],Shape]]方法有一个类似的问题。

您还应该遵循PEP 8命名规则。试试这个:

Register
,

动态创建对象的一种简单的Python方法是:

class C:
    def __init__(self):
        self.name = "C"
class D:
    def __init__(self):
        self.name = "D"

dic = {"C": C,"D": D}
x1 = dic["C"]()
x2 = dic["C"]()
print(x1 is x2)    #prints False

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。