How-To Guides¶
How to Perform Arithmetic Using eval
as a Resolver¶
Sometimes it is necessary to perform arithmetic based on settings from your app’s config. You can register Python’s builtins.eval function as a resolver to perform simple computations.
First, register the builtins.eval
function as a new resolver:
>>> from omegaconf import OmegaConf
>>> OmegaConf.register_new_resolver("eval", eval)
Now, define a config and perform some arithmetic using the eval
resolver:
>>> yaml_data = """
... ten_squared: ${eval:'10 ** 2'}
... """
>>> cfg = OmegaConf.create(yaml_data)
>>> assert cfg.ten_squared == 100
>>> cfg = OmegaConf.create({
... "ten_squared": "${eval:'10 ** 2'}",
... })
>>> assert cfg.ten_squared == 100
You can use nested interpolation to perform computation that involves other values from your config:
>>> yaml_data = """
... side_1: 5
... side_2: 6
... rectangle_area: ${eval:'${side_1} * ${side_2}'}
... """
>>> cfg = OmegaConf.create(yaml_data)
>>> assert cfg.rectangle_area == 30
>>> cfg = OmegaConf.create({
... "side_1": 5,
... "side_2": 6,
... "rectangle_area": "${eval:'${side_1} * ${side_2}'}",
... })
>>> assert cfg.rectangle_area == 30
To pass string data to eval
, you’ll need to use a nested pair of quotes:
>>> yaml_data = """
... cow_say: moo
... three_cows: ${eval:'3 * "${cow_say}"'}
... """
>>> cfg = OmegaConf.create(yaml_data)
>>> assert cfg.three_cows == "moomoomoo"
>>> cfg = OmegaConf.create({
... "cow_say": "moo",
... "three_cows": """${eval:'3 * "${cow_say}"'}"""
... })
>>> assert cfg.three_cows == "moomoomoo"
The double quotes around "${cow_say}"
guarantee that eval
will
interpret "moo"
as a string instead of as a variable moo
. See
Escaping in interpolation strings for more information.
For more complicated logic, you should consider defining a specialized resolver
to encapsulate the computation, rather than relying on the general capabilities
of eval
. Follow the examples from the Custom resolvers docs.