【问题标题】:How could a mixin or factory look like using modern Python 3?使用现代 Python 3 的 mixin 或工厂看起来如何?
【发布时间】:2019-11-29 15:58:03
【问题描述】:

想象一下,我们有一些文件:
方案.py
方案.One.py
方案.Two.py
场景.*.py
...

在文件 'scheme.py' 中,我们有公共类代码以及我们需要的所有类属性。

class Scheme:
    _VAR = "Variable"
    def function_common(self):
        pass
    def function_first(self):
        return "Main_Scheme"
    def function_second(self):
        return "Common_Scheme"

在其他文件中,我们只有特定的属性,我们想在公共类中替换它们。

文件'scheme.One.py':

class Scheme:
    _VAR = "Scheme1"
    def function_first(self):
        return "Scheme_One"

文件'scheme.Two.py':

class Scheme:
    _VAR = "Scheme2"
    def function_second(self):
        return "Second_Scheme"

我们需要通过一些参数(没有问题)来确定close scheme,并得到合适的类Scheme。
如果我们需要在文件“scheme.py”中获得类似“类工厂”的情况,那么这种情况下的最佳实践是什么?
我不是 Python 专业人士。
请彻底回答...
任何 Python 版本 (>=3.74),感谢现代解决方案...
非常感谢!!!

【问题讨论】:

    标签: python python-3.x class design-patterns


    【解决方案1】:

    您可以拥有一个封装所有指定文件的工厂。

    假设您有另一个带有函数的单独模块:makeS3()

    class Main_Scheme:
        _VAR = "Variable"
        def function_common(self):
            pass
        def function_first(self):
            return "Main_Scheme"
        def function_second(self):
            return "Common_Scheme"
    
    class Scheme1:
        _VAR = "Scheme1"
        def function_first(self):
            return "Scheme_One"
    
    class Scheme2:
        _VAR = "Scheme2"
        def function_second(self):
            return "Second_Scheme"
    
    _mixins = {"Scheme1":Scheme1, "Scheme2":Scheme2}
    
    def makeS3(mixin):
        class Scheme3(_mixins[mixin], Main_Scheme):
            pass
        return Scheme3()
    

    您的客户可以指定采用哪个 mixin:

    s3 = makeS3('Scheme1')
    print(s3._VAR)
    
    s3 = makeS3('Scheme2')
    print(s3._VAR)
    

    【讨论】:

    • 谢谢,但是..首先,为每个“方案案例”拥有一个特定文件的关键思想,我们可以将文件名的一部分用作确定我们可以应用的案例的脚本的信息。所以,我们不需要字典“_mixins”,就像你的例子一样。另外,对于想要使用这个系统的最终用户来说,这真的很简单——只需在文件开始和同一个类中创建一个具有一些新类属性的文件名称 - 只是“方案”。其次,对我来说,“黑暗面”是函数的组合,它从复制“方案”类中构造目标类,方法是用新方案替换所选文件中的特定属性。
    • 那么你真的是说最终用户提供他们自己的文件:class SchemeX(Main_Scheme): _VAR = "SchemeX" #plus methods
    • 是的。在 _VAR 中,他们可以将有关适用性的特定信息放在他们自己的方案中(在每个带有方案的文件中只有一个类“方案”)。确定脚本观察所有此类文件,使用方案识别适当的文件,从文件“Scheme.py”中获取具有所有可能属性的主类方案,并替换特定文件中存在的那些。
    【解决方案2】:

    我有@quamrana 解决方案的修改版本。它使用工厂类而不是工厂函数,因此如果您想在某处使用__init__(),可能会更灵活:

    class Main_Scheme:
        _VAR = "Variable"
        def function_common(self):
            pass
        def function_first(self):
            return "Main_Scheme"
        def function_second(self):
            return "Common_Scheme"
    
    class Scheme1(Main_Scheme):
        _VAR = "Scheme1"
        def function_first(self):
            return "Scheme_One"
    
    class Scheme2(Main_Scheme):
        _VAR = "Scheme2"
        def function_second(self):
            return "Second_Scheme"
    
    _mixins = {"Scheme1":Scheme1, "Scheme2":Scheme2}
    
    
    class Scheme:
    
        def __new__(cls, mixin):
    
             return _mixins[mixin]()
    
    
    s3 = Scheme('Scheme1')
    print(s3._VAR)
    
    s3 = Scheme('Scheme2')
    print(s3._VAR)
    

    (灵感来自https://stackoverflow.com/a/5953974/7919597

    【讨论】:

    • 谢谢,但是...在我看来,您的示例中没有使用“Main_Scheme”类。如果类“Scheme1”没有属性“_VAR”怎么办?在这种情况下,我们的“工厂”必须从“Main_Scheme”返回具有“_VAR”属性的对象“Scheme”。 'Factory' 始终必须返回整个“Main_Scheme”类,但替换此文件中存在的相应文件(Scheme.One.py、Scheme.Two.py)中的那些属性。
    猜你喜欢
    • 2012-02-23
    • 1970-01-01
    • 2014-01-21
    • 2011-03-20
    • 1970-01-01
    • 1970-01-01
    • 2011-01-28
    • 2013-10-26
    • 1970-01-01
    相关资源
    最近更新 更多