Placeholders & Expressions¶
Placeholders let you reference one config value from another using ${key} syntax. This avoids duplicating values and lets EzConfy wire objects together automatically.
Basic References¶
Reference a top-level key:
num_classes: 10
dataset:
_target_type_: my_project.data:MyDataset
_init_args_:
num_classes: ${num_classes} # resolves to 10
The placeholder ${num_classes} is replaced with the value of the num_classes key.
Attribute Access¶
Access attributes on instantiated objects with dot notation:
dataset:
_target_type_: my_project.data:MyDataset
_init_args_:
num_classes: 5
model:
_target_type_: my_project.models:Classifier
_init_args_:
output_dim: ${dataset.num_classes} # resolves to 5
Info
This works because dataset is instantiated first (EzConfy resolves dependencies), then dataset.num_classes reads the attribute from the instantiated MyDataset object.
Method Calls¶
Call methods on instantiated objects by appending ():
model:
_target_type_: torch.nn:Linear
_init_args_:
in_features: 784
out_features: 10
optimizer:
_target_type_: torch.optim:Adam
_init_args_:
params: ${model.parameters()} # calls model.parameters()
lr: 0.001
Limitation
Only no-argument methods are supported (e.g. parameters(), state_dict()).
Nested Dictionary Access¶
When a config value is a plain dictionary (no _target_type_), access nested keys with dot notation:
Arithmetic Expressions¶
Placeholders support arithmetic with +, -, *, /, //, %, and **:
lr: 0.001
warmup_lr: ${lr * 10} # 0.01
weight_decay: ${lr / 10} # 0.0001
a: 3
b: 7
total: ${a + b} # 10
half: ${a // 2} # 1
You can mix references and literals:
dataset:
_target_type_: my_project.data:MyDataset
_init_args_:
num_classes: 5
model:
_target_type_: my_project.models:Classifier
_init_args_:
hidden_dim: ${dataset.num_classes * 4} # 20
Unary operators also work:
How Dependency Resolution Works¶
EzConfy scans all ${} references, builds a dependency graph, and processes keys in topological order:
- Keys with no dependencies are resolved first
- Keys that reference already-resolved values are resolved next
- This continues until all keys are processed
Circular dependencies
If you create a circular dependency, EzConfy raises an error:
Rules and Limitations¶
Quick reference
| Rule | Example |
|---|---|
| Placeholders must be the entire value | ${key} works, prefix_${key} does not |
| Only top-level keys can be the root | ${dataset.attr} references top-level dataset, then accesses .attr |
| Method calls support no arguments | ${obj.method()} is valid, ${obj.method(42)} is not |
| Arithmetic supports only numeric operands | String concatenation is not supported |