ChainMap รวมหลาย Dictionary ให้ดูเหมือน Dictionary เดียว โดยไม่ต้อง Merge จริง อยู่ในโมดูล collections
1. การเข้าถึง Keys และ Values
import collections as col
con_code1 = {'India': 'IN', 'China': 'CN'}
con_code2 = {'France': 'FR', 'United Kingdom': 'GB'}
chain = col.ChainMap(con_code1, con_code2)
print(chain.maps) # แสดงทุก dict ภายใน
print(list(chain.keys())) # ['China', 'United Kingdom', 'India', 'France']
print(list(chain.values())) # ['CN', 'GB', 'IN', 'FR']
ลำดับค้นหา: Dict แรก -> Dict ที่สอง -> ... (Key ซ้ำ จะเอาตัวแรกที่เจอ)
2. new_child() และ Reversed
new_child(m)- เพิ่ม Dict ใหม่ไปหน้าสุด (Priority สูงสุด)reversed(chain.maps)- กลับลำดับ Priority
code = {'Japan': 'JP'}
chain = chain.new_child(code)
# [{'Japan':'JP'}, {'India':'IN',...}, {'France':'FR',...}]
chain.maps = reversed(chain.maps)
# Priority กลับด้าน: France -> India -> Japan
กรณีใช้งานจริง (Use Cases)
- Configuration Layers: Default Config -> User Config -> Env Variables -> CLI Args
- Scope Chain: Global -> Module -> Function -> Local
- Fallback Lookup: Cache -> Database -> API
ตัวอย่าง: Config Layering
import collections
defaults = {'host': 'localhost', 'port': 8080, 'debug': False}
user_config = {'port': 3000, 'debug': True}
env_config = {'host': '0.0.0.0'}
config = collections.ChainMap(env_config, user_config, defaults)
print(config['host']) # '0.0.0.0' (จาก env)
print(config['port']) # 3000 (จาก user)
print(config['debug']) # True (จาก user)
ข้อควรระวัง
- ChainMap เป็น View ไม่ได้ Copy ข้อมูล
- การแก้ไข
chain['key'] = valจะไปแก้ที่ Dict แรกเท่านั้น - ใช้
chain.new_child()สร้าง Layer ใหม่แทนการแก้ไขโดยตรง