Python 执行特殊类定义的安全方法 背景

Python 执行特殊类定义的安全方法 背景,python,python-3.x,class,Python,Python 3.x,Class,我目前正在开发一个允许将python实例序列化为xlxs文件的。我现在希望添加反序列化,但立即遇到了问题。有没有一种安全的方法可以在python中创建新的类定义而不必使用raw 在这种情况下,我需要一个load函数,该函数返回一个临时生成类的实例列表,以便反序列化状态与序列化状态相同,而不存在仅使用exec的主要安全问题。有人有合理的解决办法吗 当前方法 从复制导入deepcopy classes=[]#存储所有动态定义的类 instances=[]#存储所有动态定义的实例 定义创建类(名称:s

我目前正在开发一个允许将python实例序列化为xlxs文件的。我现在希望添加反序列化,但立即遇到了问题。有没有一种安全的方法可以在python中创建新的类定义而不必使用raw

在这种情况下,我需要一个load函数,该函数返回一个临时生成类的实例列表,以便反序列化状态与序列化状态相同,而不存在仅使用exec的主要安全问题。有人有合理的解决办法吗

当前方法
从复制导入deepcopy
classes=[]#存储所有动态定义的类
instances=[]#存储所有动态定义的实例
定义创建类(名称:str,属性:list):
“”“接受属性列表以临时生成类”“”
属性=深度复制(属性)#保留原始属性列表
属性='='','.连接(属性)+'='''
execution_string=f“”“classes.append(type({name}),(object,),dict({attributes}))”)
exec(执行字符串)
def_create_实例(名称:str,属性:list,值:list):
对于类中的当前_类:
如果当前\u类。\u名称\u==名称:
实例=当前_类()
赋值_string=“”
对于属性,zip中的值(属性,值):
赋值_string+=f“实例{attribute}='{value}'\n”
exec(赋值字符串)
instances.append(实例)
如果名称=“\uuuuu main\uuuuuuuu”:
属性=[“姓名”、“年龄”、“电子邮件”]
值=[“Kieran”,“21”,“这不是我的-email@example.com"]
打印(类)
_创建类(“User”,attributes)#动态创建一个名为User的新类,具有名称、年龄和电子邮件属性
打印(类)
打印(实例)
打印(_创建_实例(“用户”、属性、值))
打印(实例)
这本质上是动态生成的:

classes=[]
实例=[]
class.append(类型(“用户”、“对象”)、dict(名称=”、年龄=”、电子邮件=”)
instance=classes[0]()#在上面的代码中,这是通过检查类上的每个_name__值来找到的
instance.name=“Kieran”
instance.age=“21”
instance.email=“这不是我的-email@example.com"
instances.append(实例)

我相信可能有更好的方法来实现这一点。

因此我提出了两种解决方案,基本上我所关心的就是拥有类访问语义。因此,在这种情况下,我只需实例化一个namedtuple,而不需要完整的类:

从集合导入namedtuple
def\u create\u namedtuple\u类(名称:str,属性:list)->namedtuple:
返回namedtuple(名称、属性)
def\u create\u namedtuple\u实例(构造函数:namedtuple,值:list)->namedtuple:
返回构造函数。\u make(值)
如果名称=“\uuuuu main\uuuuuuuu”:
属性=['name','age','email']
值=[“Kieran”,“21”,“这不是我的-email@example.com"]
用户=\u创建\u命名耦合\u类(“用户”,属性)
k=\u创建\u命名的耦合\u实例(用户、值)
印刷品(k.名称)#基兰
印刷品(k.age)#21
打印(k.email)#这不是我的-email@example.com
另一个(对我的用例更糟)选项是使用
type()
生成一个类,然后覆盖init方法以接受实例化该类的字典:

def\u安全地创建类(名称:str,属性:list)->TypeVar(“名称”):
定义初始值(自我,**kwargs):
对于k,v在kwargs.items()中:
self.\uu dict\uu[k]=v
adict={key:“”用于属性中的键}
adict[“\uuuu init\uuuuuu”]=\ u init
返回类型(名称,(对象,),adict)
定义安全创建实例(类标识符:TypeVar(“名称”)、属性:列表、值:列表):
kvdict={k:v代表k,zip中的v(属性、值)}
返回类标识符(**kvdict)
如果名称=“\uuuuu main\uuuuuuuu”:
属性=['name','age','email']
值=[“Kieran”,“21”,“这不是我的-email@example.com"]
#安全版本
用户=\u安全地\u创建\u类(“用户”,属性)
u1=\u安全地\u创建\u实例(用户、属性、值)
打印(u1.名称)#“Kieran”
印刷品(u1.年龄)#21
打印(u1.email)#“这不是我的-email@example.com'