Subclass of :py:class:`monai.bundle.ConfigItem`, the `ConfigItem` represents an executable expression (execute based on ``eval()``, or import the module to the `globals` if it's an import statement). See also: - https://docs.python.org/3/library/functions.html#eval. For e
| 293 | |
| 294 | |
| 295 | class ConfigExpression(ConfigItem): |
| 296 | """ |
| 297 | Subclass of :py:class:`monai.bundle.ConfigItem`, the `ConfigItem` represents an executable expression |
| 298 | (execute based on ``eval()``, or import the module to the `globals` if it's an import statement). |
| 299 | |
| 300 | See also: |
| 301 | |
| 302 | - https://docs.python.org/3/library/functions.html#eval. |
| 303 | |
| 304 | For example: |
| 305 | |
| 306 | .. code-block:: python |
| 307 | |
| 308 | import monai |
| 309 | from monai.bundle import ConfigExpression |
| 310 | |
| 311 | config = "$monai.__version__" |
| 312 | expression = ConfigExpression(config, id="test", globals={"monai": monai}) |
| 313 | print(expression.evaluate()) |
| 314 | |
| 315 | Args: |
| 316 | config: content of a config item. |
| 317 | id: name of current config item, defaults to empty string. |
| 318 | globals: additional global context to evaluate the string. |
| 319 | |
| 320 | """ |
| 321 | |
| 322 | prefix = EXPR_KEY |
| 323 | run_eval = run_eval |
| 324 | |
| 325 | def __init__(self, config: Any, id: str = "", globals: dict | None = None) -> None: |
| 326 | super().__init__(config=config, id=id) |
| 327 | self.globals = globals if globals is not None else {} |
| 328 | |
| 329 | def _parse_import_string(self, import_string: str) -> Any | None: |
| 330 | """parse single import statement such as "from monai.transforms import Resize""" |
| 331 | node = first(ast.iter_child_nodes(ast.parse(import_string))) |
| 332 | if not isinstance(node, (ast.Import, ast.ImportFrom)): |
| 333 | return None |
| 334 | if len(node.names) < 1: |
| 335 | return None |
| 336 | if len(node.names) > 1: |
| 337 | warnings.warn(f"ignoring multiple import alias '{import_string}'.") |
| 338 | name, asname = f"{node.names[0].name}", node.names[0].asname |
| 339 | asname = name if asname is None else f"{asname}" |
| 340 | if isinstance(node, ast.ImportFrom): |
| 341 | self.globals[asname], _ = optional_import(f"{node.module}", name=f"{name}") |
| 342 | return self.globals[asname] |
| 343 | if isinstance(node, ast.Import): |
| 344 | self.globals[asname], _ = optional_import(f"{name}") |
| 345 | return self.globals[asname] |
| 346 | return None |
| 347 | |
| 348 | def evaluate(self, globals: dict | None = None, locals: dict | None = None) -> str | Any | None: |
| 349 | """ |
| 350 | Execute the current config content and return the result if it is expression, based on Python `eval()`. |
| 351 | For more details: https://docs.python.org/3/library/functions.html#eval. |
| 352 |
no outgoing calls
searching dependent graphs…