Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
对对象的YAML解析(PyYAML-Python3)_Python_Pyyaml - Fatal编程技术网

对对象的YAML解析(PyYAML-Python3)

对对象的YAML解析(PyYAML-Python3),python,pyyaml,Python,Pyyaml,我有以下代码: class Settings: def __init__(self, annual_volatility_target): self.annual_volatility_target = annual_volatility_target self.daily = annual_volatility_target/np.sqrt(252) def yaml_load(name): with open('yaml/' + str(na

我有以下代码:

class Settings:
    def __init__(self, annual_volatility_target):
        self.annual_volatility_target = annual_volatility_target
        self.daily = annual_volatility_target/np.sqrt(252)

def yaml_load(name):
    with open('yaml/' + str(name) + '.yaml', 'r') as ymlfile:
        return yaml.load(ymlfile)

settings = yaml_load("settings")
使用以下YAML:

!!python/object:v.Settings
annual_volatility_target: 0.25
问题是,当我加载
设置时,
设置。未设置每日设置<代码>设置。无论我是否在
\uuuuu init\uuuu
中这样说,年度波动率目标都是

如果我手动实例化一个
Settings
对象(即不使用PyYAML),它可以正常工作


我做错了什么?

一种可能是为
设置编写一个

import yaml
import numpy as np

class Settings:
    def __init__(self, annual_volatility_target):
        self.annual_volatility_target = annual_volatility_target
        self.daily = annual_volatility_target/np.sqrt(252)

def yaml_load(name):
    with open(str(name) + '.yaml', 'r') as ymlfile:
        return yaml.load(ymlfile)

def settings_constructor(loader, node):
    fields = loader.construct_mapping(node)
    return Settings(fields['annual_volatility_target'])

yaml.add_constructor('!v.Settings', settings_constructor)

settings = yaml_load("settings")

print(settings.annual_volatility_target)
print(settings.daily)
!v.Settings
annual_volatility_target: 0.25
我必须使用一个修改过的
yaml
文件(我无法使它与注释
!!python/object:v.Settings
):


PyYAML中的Python对象是在两步过程中构造的。首先调用
\uuuuu new\uuuuuu
(在
构造函数中。生成python实例()
),然后设置属性(在
构造函数中。设置python实例状态()
)。需要这两个步骤,因为YAML支持对对象的引用,如果该对象(间接地)是自引用的,则无法一次性构造该对象,因为它所依赖的参数(包括自身)还不可用

你可以用两种方法来解决这个问题。您可以为
设置
定义
\uuuuuu setstate\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu()
,该设置将通过
dict调用,并从
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

import yaml

yaml_str = """\
!!python/object:try.Settings
annual_volatility_target: 0.25
"""

class Settings:
    def __init__(self, annual_volatility_target):
        self.__setstate__({annual_volatility_target: annual_volatility_target})

    def __setstate__(self, kw):
        self.annual_volatility_target = kw.get('annual_volatility_target')
        self.daily = self.annual_volatility_target/np.sqrt(252)

    def __repr__(self):
        return "Setting({}, {})".format(self.annual_volatility_target, self.daily)

settings = yaml.load(yaml_str)

print(settings)
另一个更通用(非PyYAML)的解决方案是在第一次访问时创建
每日
值:

class Settings:
    def __init__(self, annual_volatility_target):
        self.annual_volatility_target = annual_volatility_target

    @property:
    def daily(self):
         return annual_volatility_target/np.sqrt(252)
如果您经常访问
daily
,则应在第一次计算值时将其缓存在例如
self.\u daily

class Settings:
    def __init__(self, annual_volatility_target):
        self.annual_volatility_target = annual_volatility_target
        self._daily = None

    @property:
    def daily(self):
         if self._daily is None:  
             self._daily = annual_volatility_target/np.sqrt(252)
         return self._daily

虽然第二个答案对我来说似乎更容易,但第一个答案更完整,包含了有价值的数据。@Srgrn哪一个是第一个,哪一个是第二个?我真蠢。你的是第一个。你不必写构造函数。PyYAML有内置机制(
\uuu setstate\uuu
,子类化
yaml.YAMLObject
)来处理对象加载。我使用了您的解决方案,但更进一步,删除了u init\uuu(),因为正如我所知,PyYAML从未调用过它。有什么理由让我把它留在里面吗?@cjm2671如果你想在测试例程等中实例化类的对象,有
\uuu init\uuu()
会很有帮助,但你真的不必有它。