我遇到的情况是复杂的对象可以通过package.subpackage.MYOBJECT
等唯一名称引用。虽然可以使用标准的pickle算法来挑选这个对象,但结果数据字符串会非常大。
我正在寻找一种方法来为类和函数已经存在的对象获得相同的pickling语义:Python的pickle只是转储它们的完全限定名,而不是代码。这样就可以转储像package.subpackage.MYOBJECT
这样的字符串,并且会导入unpickling对象,就像函数或类一样。
似乎这个任务归结为让对象知道它所绑定的变量名,但我没有线索如何去做。
这是一个简短的例子来清楚地解释自己(明显的导入被忽略)。
文件bigpackage / bigclasses / models.py:
class SomeInterface():
__meta__ = ABCMeta
@abstractmethod
def operation():
pass
class ImplementationA(SomeInterface):
def operation():
print "ImplementationA"
class ImplementationB(SomeInterface):
def operation():
print "ImplementationB"
IMPL_A = ImplementationA()
IMPL_B = ImplementationB()
文件bigpackage / bigclasses / tasks.py:
@celery.task
def background_task(impl, somearg):
assert isinstance(impl, SomeInterface)
impl.operation()
print somearg
文件bigpackage / bigclasses / work.py:
from bigpackage.bigclasses.models import IMPL_A, IMPL_B
from bigpackage.bigclasses.tasks import background_task
background_task.submit(IMPL_A, "arg1")
background_task.submit(IMPL_B, "arg2")
这里我有一个简单的背景Celery任务,它接受SomeInterface
的两个可用实现之一作为参数。任务的参数由Celery腌制,传递到队列并在某个工作服务器上执行,该服务器运行完全相同的代码库。我的想法是避免对IMPL_A
和IMPL_B
进行深度腌制,而是相应地将它们作为bigpackage.bigclasses.models.IMPL_A
和bigpackage.bigclasses.models.IMPL_B
传递。这将有助于提高队列服务器的性能和总流量,并为IMPL_A
和IMPL_B
中的更改提供一些安全性,这些更改将使它们成为非pickleable(例如,对象属性层次结构中的lambda)。