Python:TypeError:出于安全原因,不允许对AuthenticationString对象进行腌制 [英] Python: TypeError: Pickling an AuthenticationString object is disallowed for security reasons
问题描述
我正在创建一个类的对象(具有 multiprocessing
),并将其添加到 Manager.dict()
中,以便可以从字典中删除该项目完成工作后,该对象(该项目所指向的对象)内部的对象.
我尝试了以下代码:
来自多处理导入管理器的 ,流程类My_class(Process):def __init __():超级(My_class,self).__ init __()打印对象",自我,已创建".def运行(自己):打印对象",自我,过程已启动".manager = Manager()object_dict = manager.dict()对于范围(2)中的x:object_dict [x] = My_class()object_dict [x] .start()
但是我遇到了一个错误:
TypeError:不允许对AuthenticationString对象进行腌制出于安全原因
出于好奇,我删除了多处理部分,并尝试如下操作:
来自多处理导入管理器的 类My_class():def __init __():打印对象",自我创建".manager = Manager()object_dict = manager.dict()对于范围(2)中的x:object_dict [x] = My_class()
它没有给我任何错误,并显示了两个对象的地址.
那是什么错误,以及如何解决?
以下是复制您看到的效果的较短方法:
来自多处理导入过程的 进口泡菜p = Process()pickle.dumps(p._config ['authkey'])
TypeError:不允许对AuthenticationString对象进行腌制出于安全原因
这里实际发生的是以下内容: 由于您不能腌制 现在,让我们看看它们与您的代码之间的关系.您创建一个 简而言之,您可以自由使用 I'm creating an object of a class(with I tried the following code: But I got an error: For curiosity, I removed the multiprocessing part, and tried like: and it's giving me no errors and displaying the addresses of two objects. What's that error and how to make it go away? Here is a shorter way to replicate the effect you are seeing:
TypeError: Pickling an AuthenticationString object is disallowed
for security reasons What is actually happening here is the following: the The rationale behind this choice is the following: the authkey is used for authenticating inter-process communication messages between parent and child processes (e.g. between the workers and the main process) and exposing it anywhere outside the initial process family could pose a security risk (because you could, in principle, impersonate a "parent process" for the worker and force it into executing arbitrary code). As pickling is the most common form of data transfer in Python, prohibiting it is a simple way of an unintended exposure of the authkey. As you cannot pickle an Now let us take a look at how it all relates to your code. You create a In short, you are free to use 这篇关于Python:TypeError:出于安全原因,不允许对AuthenticationString对象进行腌制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋! process._config ['authkey']
是 AuthenticationString
,因此也不能腌制 Process
类或其任何子类的实例(因为它们都在字段中包含身份验证密钥) Manager
对象,并尝试设置其 dict
的值. Manager
实际上是在一个单独的进程中运行,每当您将任何数据分配给 manager.dict()
时,Python都需要将该数据传输到 Manager的
自己的过程.为了进行这种传输,需要对数据进行腌制.但是,从前几段我们知道,您不能使 Process
对象腌制,因此根本无法将它们保留在共享的 dict
中. manager.dict()
共享任何对象,除了那些不能被腌制的对象,例如 Process
对象.>multiprocessing
) and adding it to a Manager.dict()
so that I can delete the item from the dictionary inside the object (the item points to) when its work completes..from multiprocessing import Manager, Process
class My_class(Process):
def __init__(self):
super(My_class, self).__init__()
print "Object", self, "created."
def run(self):
print "Object", self, "process started."
manager=Manager()
object_dict=manager.dict()
for x in range(2):
object_dict[x]=My_class()
object_dict[x].start()
TypeError: Pickling an AuthenticationString object is disallowed
for security reasons
from multiprocessing import Manager
class My_class():
def __init__(self):
print "Object", self, "created."
manager=Manager()
object_dict=manager.dict()
for x in range(2):
object_dict[x]=My_class()
from multiprocessing import Process
import pickle
p = Process()
pickle.dumps(p._config['authkey'])
process._config['authkey']
is the secret key that the Process
object gets assigned on creation. Although this key is nothing more but a sequence of bytes, Python uses a special subclass of bytes
to represent it: AuthenticationString
. This subclass differs from the usual bytes
in only one aspect - it refuses to be pickled.AuthenticationString
, you also cannot pickle instances of Process
class or any of its subclasses (because all of them contain an authentication key in a field).Manager
object and attempt to set the values of its dict
. The Manager
actually runs in a separate process and whenever you assign any data to manager.dict()
, Python needs to transfer this data to the Manager's
own process. For that transfer to happen, the data is being pickled. But, as we know from the previous paragraphs, you cannot pickle Process
objects and hence cannot keep them in a shared dict
at all.manager.dict()
to share any objects, except those which cannot be pickled, such as the Process
objects.