如何使用同一个类生成多个不同属性的对象?

问题描述 投票:0回答:1

我在做一个在线系统的Python包,开始实现装饰器,是这样的。

@Service
class MyCode ():
  # This will run once on beginning
  def setup (self):
    pass
  # This will run once on every loop
  def main (self):
    pass
  # This will run on an exclusive thread forever (or until program shuts down)
  def loop (self):
    pass

我想实现一个 Swarm 装饰者,如

@Swarm (10)
class MyCode ():
  pass

将产生10个实例 MyCode 诸如 MyCode_OMyCode_9,每个人都不一样。

我的 Service decorator对于单个实例来说工作正常,是这样的。

from copy import deepcopy

class Service ():
  def __init__ (self, obj, context = None, name=None):
    @wraps(obj)
    def init(obj, context = None):
      try:
        if name:
          self.__name = name
        else:
          self.__name = obj.name
      except:
          self.__name = obj.__name__
      self.__context = context
      self.__rawObj = deepcopy(obj)
      self.__obj = deepcopy(obj)
      self.__obj.__init__(self.__obj)
      self.__obj.MSG_VERBOSE  = self.MSG_VERBOSE
      self.__obj.MSG_DEBUG    = self.MSG_DEBUG
      self.__obj.MSG_INFO     = self.MSG_INFO
      self.__obj.MSG_WARNING  = self.MSG_WARNING
      self.__obj.MSG_ERROR    = self.MSG_ERROR
      self.__obj.MSG_FATAL    = self.MSG_FATAL
      try:
        self.seed = self.__obj.seed
      except:
        self.seed = 0
      self._active = True
    return init(obj, context=None)

这个 self.seed 只用于调试。

我试图实现 Swarm 像这样。

class Swarm ():
  def __init__ (self, size=1, obj=None, context=None):

    self.__context = context
    self.__services = []
    self.__name = "Otools Swarm <None>"
    self.__size = size
    if obj:
      self.__call__(obj)
    self._active = True

  def __call__ (self, obj, context=None, index=None):

    @wraps(obj)
    def init(obj, index=0):
      obj.__init__(obj)
      new_obj = deepcopy(obj)
      self.__rawObj = deepcopy(new_obj)
      self.__name = new_obj.__name__
      new_obj.name = "{}_{}".format(new_obj.__name__, index)
      svc = Service(new_obj)
      self.__services.append(svc)

    for i in range(self.size):
      init(obj, i)

    for service in self.__services:
      print ("SERVICE_DATA:", service.name, service.seed)
      print ("OBJ_DATA:", service.obj.name, service.obj.seed)

    return self

但后来那些 print的给我看这个。

SERVICE_DATA: SwarmTest_0 2199
OBJ_DATA: SwarmTest_4 2643
SERVICE_DATA: SwarmTest_1 4148
OBJ_DATA: SwarmTest_4 2643
SERVICE_DATA: SwarmTest_2 1438
OBJ_DATA: SwarmTest_4 2643
SERVICE_DATA: SwarmTest_3 1341
OBJ_DATA: SwarmTest_4 2643
SERVICE_DATA: SwarmTest_4 2643
OBJ_DATA: SwarmTest_4 2643

我试过在很多地方添加深层拷贝,试过不调用。__init__ 对象上,我不知道还能做什么。

python python-3.x instance deep-copy
1个回答
0
投票

多亏了@chepner,我有了一个想法,并解决了这个问题。

我的解决方案。

Service.py

class Service ():
  """
  A Service is a class that shall encapsulate your own class in order to 
  attach it into a context. It has four core methods: "setup", 
  "main", "loop" and "finalize". The "setup" method will run once.
  The "main" method will run once every execution loop on the main
  thread. The "loop" method will loop forever, unless the service is
  diabled. The "finalize" method will run when the program shuts down.
  """

  def __init__ (self, obj, context = None, name=None):
    @wraps(obj)
    def init(obj, context = None):
      self.__obj = obj()
      self.__context = context
      self.__rawObj = deepcopy(obj)
      try:
        if name:
          self.__name = name
        else:
          self.__name = self.__obj.name
      except:
          self.__name = self.__obj.__class__.__name__
      self.__obj.name = self.__name
      self.__obj.MSG_VERBOSE  = self.MSG_VERBOSE
      self.__obj.MSG_DEBUG    = self.MSG_DEBUG
      self.__obj.MSG_INFO     = self.MSG_INFO
      self.__obj.MSG_WARNING  = self.MSG_WARNING
      self.__obj.MSG_ERROR    = self.MSG_ERROR
      self.__obj.MSG_FATAL    = self.MSG_FATAL
      self._active = True
    return init(obj, context=context)

Swarm.py

class Swarm ():
  """
  A Swarm helps deploying multiple similar Service objects
  by handling everything the user should do in order to deploy
  them with much fewer lines of code.
  """

  def __init__ (self, size=1, obj=None, context=None):

    self.__context = context
    self.__services = []
    self.__name = "Otools Swarm <None>"
    self.__objName = None
    self.__size = size
    if obj:
      self.__call__(obj)
    self._active = True

  def __call__ (self, obj, context=None, index=None):

    @wraps(obj)
    def init(obj, index=0):
      self.__objName = obj.__name__
      new_obj = deepcopy(obj)
      self.__rawObj = deepcopy(new_obj)
      new_obj.name = "{}_{}".format(self.__objName, index)
      svc = Service(new_obj)
      self.__services.append(svc)

    for i in range(self.size):
      init(obj, i)

    return self

就能正常运行了。

完整的代码。https:/github.comgabriel-milanotools。

© www.soinside.com 2019 - 2024. All rights reserved.