from collections import ChainMap # Define multiple dictionaries, simulating different configuration layers defaults = {'debug': False, 'log_level': 'INFO', 'port': 8000} user_config = {'log_level': 'DEBUG', 'timeout': 30} cli_args = {'port': 9000} # Create a ChainMap, order matters (later maps override earlier ones) config = ChainMap(cli_args, user_config, defaults) print(f"Combined config (port): {config['port']}") # Output: 9000 (from cli_args) print(f"Combined config (log_level): {config['log_level']}") # Output: DEBUG (from user_config) print(f"Combined config (debug): {config['debug']}") # Output: False (from defaults) print(f"Combined config (timeout): {config['timeout']}") # Output: 30 (from user_config) # Adding a new dictionary to the chain new_env_vars = {'host': 'localhost'} config = config.new_child(new_env_vars) print(f"Combined config (host) after adding new_env_vars: {config['host']}") # Modifying a value in one of the underlying maps reflects in ChainMap cli_args['port'] = 9001 print(f"Combined config (port) after cli_args modification: {config['port']}") # Accessing non-existent key raises KeyError try: print(config['non_existent']) except KeyError as e: print(f"Error accessing non-existent key: {e}") # Accessing all contained maps print(f"All maps in chain: {config.maps}")