【问题标题】:How realize factory pattern for objects generate?如何实现对象生成的工厂模式?
【发布时间】:2015-12-05 08:56:44
【问题描述】:

请帮助解决问题。我尝试使用工厂模式生成对象“船”:

from datetime import datetime, date, time
import pprint
import random

class Boat(object):
  def __init__(self, name, max_peoples, max_speed, color_num, oars):
    self.max_peoples = max_peoples
    self.max_speed = max_speed
    self.color_num = color_num
    self.oars = oars
    self.name = name

  def __str__(self):
    return str(self.__class__.__name__) + ': ' + str(self.__dict__)   

class BoatFactory(object):
  def __init__(self, num):
    return Boat(
      name='beda_'+str(num), 
      max_peoples=random.randint(5, 10), 
      max_speed=(random.randint(5, 10)) * 10, 
      color_num=random.randint(1, 5), 
      oars=random.randint(1, 2)
    )    

class FloatFactory(object):
  def __init__(self, num, factory):
    return factory(num)

class World(object):
  def __new__(cls,*dt,**mp):
    if cls.obj is None:
      cls.obj = object.__new__(cls,*dt,**mp)

    return cls.obj    

  def __init__(self):
    self.boats = []

    for i in range(4):
      self.boats.append(FloatFactory(num=i, factory=BoatFactory))

  obj = None

if __name__ == '__main__':
  world1 = World()

  for boat in world1.boats:
    print(boat)

但是,运行脚本后,我收到以下错误消息:

(python3_env)kalinin@kalinin ~/python3/python3_files/boats6 $ python
index.py Traceback (most recent call last):

  File "index.py", line 61, in <module>
    world1 = World()

  File "index.py", line 55, in __init__
    self.boats.append(FloatFactory(num=i, factory=BoatFactory))

  File "index.py", line 41, in __init__
    return factory(num)
     TypeError: __init__() should return None, not 'Boat'

请帮我修复此代码。

【问题讨论】:

    标签: python factory


    【解决方案1】:

    __init__ cannot return non-None value,你可以把工厂变成函数:

    ##class BoatFactory(object):
    ##  def __init__(self, num):
    ##    return Boat(
    ##      name='beda_'+str(num), 
    ##      max_peoples=random.randint(5, 10), 
    ##      max_speed=(random.randint(5, 10)) * 10, 
    ##      color_num=random.randint(1, 5), 
    ##      oars=random.randint(1, 2)
    ##    )    
    
    def BoatFactory(num):
        return Boat(
          name='beda_'+str(num), 
          max_peoples=random.randint(5, 10), 
          max_speed=(random.randint(5, 10)) * 10, 
          color_num=random.randint(1, 5), 
          oars=random.randint(1, 2)
        )
    
    ##class FloatFactory(object):
    ##  def __init__(self, num, factory):
    ##    return factory(num)
    
    def FloatFactory(num, factory):
        return factory(num)
    

    你也可以让你的类可调用,见__call__:

    class BoatFactory(object):
      def __call__(self, num):
        return Boat(
          name='beda_'+str(num), 
          max_peoples=random.randint(5, 10), 
          max_speed=(random.randint(5, 10)) * 10, 
          color_num=random.randint(1, 5), 
          oars=random.randint(1, 2)
        )    
    
    
    class FloatFactory(object):
      def __call__(self, num, factory):
        return factory()(num)
    
    
    class World(object):
      def __new__(cls,*dt,**mp):
        if cls.obj is None:
          cls.obj = object.__new__(cls,*dt,**mp)
    
        return cls.obj    
    
      def __init__(self):
        self.boats = []
    
        for i in range(4):
          self.boats.append(FloatFactory()(num=i, factory=BoatFactory))
    
      obj = None
    

    或者只是将__init__ 更改为__new__:

    class BoatFactory(object):
      def __new__(self, num):
        return Boat(
          name='beda_'+str(num), 
          max_peoples=random.randint(5, 10), 
          max_speed=(random.randint(5, 10)) * 10, 
          color_num=random.randint(1, 5), 
          oars=random.randint(1, 2)
        )    
    
    
    class FloatFactory(object):
      def __new__(self, num, factory):
        return factory(num)
    

    但我发现第一个选项最易读

    【讨论】:

    • __new__ 版本有点奇怪,它是对语言机制的劫持。不过前两个版本还不错。 #1 如果不需要上下文,#2 是一种优雅的方式来封装上下文,同时保持类似函数的语法,只有在工厂也有一个接受上下文的构造函数时才有意义。
    猜你喜欢
    • 2016-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-12
    • 1970-01-01
    • 1970-01-01
    • 2012-05-08
    • 1970-01-01
    相关资源
    最近更新 更多