如何使用safe_load使用PyYAML反序列化对象?

sys*_*out 7 python pyyaml deserialization

有一个这样的片段:

import yaml
class User(object):
    def __init__(self, name, surname):
       self.name= name
       self.surname= surname

user = User('spam', 'eggs')
serialized_user = yaml.dump(user)
#Network
deserialized_user = yaml.load(serialized_user)
print "name: %s, sname: %s" % (deserialized_user.name, deserialized_user.surname)
Run Code Online (Sandbox Code Playgroud)

Yaml docs说,使用从不受信任的来源收到的任何数据调用yaml.load是不安全的; 那么,我应该修改我的snippet\class以使用safe_load方法?
可能吗?

Pet*_*rin 23

存在另一种方式.来自PyYaml文档:

python对象可以标记为安全,因此可以被yaml.safe_load识别.为此,从yaml.YAMLObject [...]派生它,并将其类属性yaml_loader显式设置为yaml.SafeLoader.

您还必须设置yaml_tag属性才能使其正常工作.

YAMLObject执行一些元类魔法来使对象可加载.请注意,如果执行此操作,对象将只能由安全加载程序加载,而不能使用常规yaml.load()加载.

工作范例:

import yaml

class User(yaml.YAMLObject):
    yaml_loader = yaml.SafeLoader
    yaml_tag = u'!User'

    def __init__(self, name, surname):
       self.name= name
       self.surname= surname

user = User('spam', 'eggs')
serialized_user = yaml.dump(user)

#Network

deserialized_user = yaml.safe_load(serialized_user)
print "name: %s, sname: %s" % (deserialized_user.name, deserialized_user.surname)
Run Code Online (Sandbox Code Playgroud)

这个的优点是它很容易做到; 缺点是它只适用于safe_load,并且使用与序列化相关的属性和元类使您的类变得混乱.


Ben*_*son 11

根据定义,safe_load似乎不允许您反序列化自己的类.如果你想要它是安全的,我会做这样的事情:

import yaml
class User(object):
    def __init__(self, name, surname):
       self.name= name
       self.surname= surname

    def yaml(self):
       return yaml.dump(self.__dict__)

    @staticmethod
    def load(data):
       values = yaml.safe_load(data)
       return User(values["name"], values["surname"])

user = User('spam', 'eggs')
serialized_user = user.yaml()
print "serialized_user:  %s" % serialized_user.strip()

#Network
deserialized_user = User.load(serialized_user)
print "name: %s, sname: %s" % (deserialized_user.name, deserialized_user.surname)
Run Code Online (Sandbox Code Playgroud)

这里的优点是您可以绝对控制类(de)序列化的方式.这意味着您不会通过网络获得随机可执行代码并运行它.缺点是您可以绝对控制类(de)序列化的方式.这意味着你必须做更多的工作.;-)