是否可以通过引用(通过名称)pickle Python对象?
我遇到过这样一种情况:有一个复杂的对象,它可以被唯一的名称引用,比如是否可以通过引用(通过名称)pickle Python对象?,python,celery,pickle,Python,Celery,Pickle,我遇到过这样一种情况:有一个复杂的对象,它可以被唯一的名称引用,比如package.subpackage.MYOBJECT。虽然可以使用标准pickle算法对该对象进行pickle,但生成的数据字符串将非常大 我正在寻找某种方法来为已经在这里的类和函数的对象获得相同的pickle语义:Python的pickle只是转储它们的完全限定名,而不是代码。这样,像package.subpackage.MYOBJECT这样的字符串将被转储,并且在取消勾选时将导入对象,就像函数或类一样 这项任务似乎归结为让
package.subpackage.MYOBJECT
。虽然可以使用标准pickle算法对该对象进行pickle,但生成的数据字符串将非常大
我正在寻找某种方法来为已经在这里的类和函数的对象获得相同的pickle语义:Python的pickle只是转储它们的完全限定名,而不是代码。这样,像package.subpackage.MYOBJECT这样的字符串将被转储,并且在取消勾选时将导入对象,就像函数或类一样
这项任务似乎归结为让对象知道它绑定的变量名,但我不知道如何做
这里有一个简短的例子来清楚地解释我自己(跳过明显的导入)
文件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")
这里我有一个简单的背景芹菜任务,它接受SomeInterface
的两个可用实现之一作为参数。任务的参数由芹菜腌制,传递到队列并在运行完全相同代码库的某个工作服务器上执行。我的想法是避免对IMPL_A
和IMPL_B
进行深度酸洗,而是将它们作为bigpackage.bigclasses.models.IMPL_A
和bigpackage.bigclasses.models.IMPL_B
传递。这将有助于提高队列服务器的性能和总流量,还可以提供一些安全性,防止IMPL_A
和IMPL_B
中的更改使它们不可pickle(例如对象属性层次结构中的任意lambda)。我认为这不是pickle
设计的目的。如果package.subpackage.MYOBJECT
的类型是实例(而不是类),那么您也可以只保存名称package.subpackage.MYOBJECT
,然后再次导入。不幸的是,我被迫使用pickle。这个问题出现在芹菜系列化的背景下。当然,我可以显式地将实例的名称传递给类构造函数,但这会使此类实例更难在包之间移动,这是我们经常做的事情。我希望有某种方法可以自动推断出这个名字。它可能会帮助我们提出解决方案,@Michael,如果你能提供一个最小的代码片段/脚本,来演示这个问题。@boardrider,谢谢你的建议。我已经用示例更新了我的原始问题。您是否有一个或至少有限数量的“字典”可以找到命名对象?如果没有,您是否有办法以某种方式注册此类对象,以便某些中心位置知道命名对象(但可能不知道未命名的临时对象)?