【问题标题】:Python and factoriesPython 和工厂
【发布时间】:2009-10-30 18:41:06
【问题描述】:

我似乎无法掌握工厂的正确概念。

谁能帮我编写一个简单的测试代码?我在互联网上阅读了一些文本,但无法以相同的方式对其进行编码。其实我无法理解这个过程。复制代码很容易,但我需要了解为什么这行不通。

class Factory:

    def __init__(self):
        self.msg = "teste"

    def fabricateAnotherObject(self,obj,**kwargs):
        return apply(obj,**kwargs)

class testClass:
    def __init__(self,nome,salario,endereco):
        self.nome = nome
        self.salario = salario
        self.endereco = endereco

    def __str__(self):
        return "Nome: " + str(self.nome) + "\nEndereco: " + str(self.endereco) + "\nSalario: " + str(self.salario) 

a = Factory()
emp = a.fabricateAnotherObject(testClass,"George",2000,"Three Four Five Avenue")
print str(emp)

【问题讨论】:

  • 您对apply() 的使用是错误的(它不接受关键字参数),但无论如何apply() 已被弃用,使用obj(**kwargs) 语法。

标签: python oop factory


【解决方案1】:

您的代码适得其反(对不起,我必须说出来)。

工厂的意义是,您不必在创建它的位置知道构造对象的类。

原因是,对象创建在面向对象的抽象中造成了差距。您必须具体地创建对象。但有时你只是想创建一个具有某种行为的对象,但其他人应该(集中地)决定它是什么具体类。

例如,您必须在 100 个地方创建一种对象。但后来你可能会发现,你必须改变班级——你必须改变所有这些地方。

工厂将通过定义一个您必须更改的地方来消除这种需求。

最简单的工厂是:

def fabricateAnotherObject(self, **kwargs):
    return testClass(**kwargs)

当然,这在某些情况下可能没什么帮助。所以一些工厂也可能从 db 或其他配置中加载类名。但最简单的解决方案是对象的硬编码构造——在我们的示例中,当您选择始终调用此方法时,只需更改此方法。

一个更动态的解决方案(不需要数据库):

class Factory(object):
   def __init__(self, theClass):
       self.theClass = theClass
   def create(self, **kwargs):
       self.theClass(**kwargs)

myFactory = Factory(testClass)

myFactory 实例可以在不同的位置用于创建正确的实例。问题是,如何在一些特殊模块中初始化 myFactory??

【讨论】:

  • 当然在我构建的例子中,你不需要工厂类——一个简单的工厂函数就足够了,你可以看到没有使用自参数。
  • 于尔根。这正是我所需要的。我必须感谢你的话。这里发布的只是一个示例。
  • 哦刚刚意识到对象是固定的。我有点需要被选择。我会想到一些事情。谢谢:D
  • 我不知道,如果我理解你的话。你需要更多的动态?这也行。我会将其添加到答案中。
  • 类对象是 Python 中的一等公民。这意味着你不需要创建一个特殊的工厂,你可以直接传递类对象,就像传递一个整数或字符串一样。
【解决方案2】:

工厂模式适用于不允许函数(和类)作为一阶值的编程语言(例如 C++ 或 Java)。

这个想法是,您将“工厂”类的实例作为参数传递给某个函数(或方法或构造函数),然后用于生成新的对象实例(通常这些是某个特定子类的实例预先知道的超类)。

在 Python 中,您可以只传递类(因为类(和函数)也是对象)。

【讨论】:

    【解决方案3】:

    另见type() 在 docs.python.org/library/functions 中:

    类型(名称、基数、字典)

    返回一个新的类型对象。这本质上是类语句的动态形式。 name 字符串是类名,成为 __name__ 属性; 基元组逐项列出基类并成为 __bases__ 属性; 并且 dict 字典是包含类主体定义的命名空间 并成为 __dict__ 属性。 例如,以下两个语句创建相同类型的对象:

    class X(object):
        a = 1
    X = type('X', (object,), dict(a=1))
    

    对于一个使用工厂的简短真实程序(紧凑地构建许多特殊的字典),请参阅 ofc2.py .
    各位高手,请多举个例子?

    【讨论】:

      【解决方案4】:

      你的制作方法应该是这样的:

          def fabricateAnotherObject(self, obj, *args):
              return apply(obj, args)
      

      apply() 接受参数列表。通过在您的fabricateAnotherObject 方法中使用*args,您可以将obj 之外的所有参数作为一个可以传递给apply() 的列表来使用。

      【讨论】:

        猜你喜欢
        • 2011-01-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多