<p>PyYAML中的Python对象是通过两个步骤构建的。首先调用<code>__new__</code>(在<code>Constructor.make_python_instance()</code>)然后设置属性(在<code>Constructor.set_python_instance_state()</code>)。这两步过程是必需的,因为YAML支持对对象的引用,并且如果该对象(间接地)是自引用的,则无法一次性构造它,因为它所依赖的参数(包括自身)还不可用。在</p>
<p>你可以用两种方法来解决这个问题。您可以为<code>Settings</code>定义<code>__setstate__()</code>,它将用<code>dict</code>调用,并从<code>__init__()</code>调用:</p>
<pre><code>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)
</code></pre>
<p>另一个更通用的(非PyYAML)解决方案是在第一次访问时创建<code>daily</code>值:</p>
^{pr2}$
<p>如果您经常访问<code>daily</code>,那么您应该在第一次计算值时将其缓存到例如<code>self._daily</code>中:</p>
<pre><code>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
</code></pre>