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



我正在为在线系统开发一个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

将生成具有类似MyCode_OMyCode_9的名称的MyCode的10个实例,每个实例彼此不同。

我的Service装饰器可以很好地处理单个实例,它是这样的:

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

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

感谢@chepner,我有了一个想法并解决了它。

我的解决方案:

提供的服务

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.com/gabriel-milan/otools

最新更新