PyYAML 中的 Python 对象是通过两步过程构建的。第一的__new__
被称为(在Constructor.make_python_instance()
)然后设置属性(在Constructor.set_python_instance_state()
)。需要这两个步骤的过程是因为 YAML 支持对对象的引用,并且如果该对象是(间接)自引用的,则无法一次性构造它,因为它所依赖的参数(包括其自身)尚不可用。
您可以通过两种方式解决这个问题。您可以定义__setstate__()
for Settings
这将被称为dict
并从__init__()
还有:
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)的解决方案是创建daily
第一次访问时的值:
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._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