如何让Monitor类实例在match case中以元组形式匹配?
问题与解决方案
问题
我有一台戴尔二合一平板(Windows 11,平板模式下屏幕可旋转),正在编写脚本根据显示器方向调整应用窗口大小。需要让Monitor类的实例monitor = Monitor()能在Python的match case语句中以元组形式匹配,但目前仅能通过monitor == monitor()做相等比较,无法匹配元组模式。
解决方案
要让自定义类实例支持match case的元组模式匹配,需添加__match_args__类属性,指定匹配时对应的位置字段;同时修正迭代相关的错误实现:
- 添加
__match_args__:该属性定义了match case元组模式匹配时,实例会被解构为哪些属性/值,直接对应我们需要的分辨率宽高。 - 移除错误的
__next__方法:__iter__已经返回了self._monitor的迭代器,无需手动实现__next__,否则会导致迭代逻辑冲突。
修改后的完整代码
from win32api import GetMonitorInfo, MonitorFromPoint from typing import Optional class Monitor: # 定义match case元组匹配对应的字段 __match_args__ = ('Width', 'Height') def __init__(self): self._monitor: Optional[tuple] = None self.update() @property def Width(self) -> int: return self._monitor[0] @property def Height(self) -> int: return self._monitor[1] def update(self): self._monitor = self() def __call__(self) -> tuple: return GetMonitorInfo(MonitorFromPoint((0, 0)))['Monitor'][2:] def __iter__(self): return iter(self._monitor) def __getitem__(self, index): return self._monitor[index] def __eq__(self, other): return self._monitor == other def __str__(self): return str(self._monitor) def __repr__(self): return str(self._monitor) if __name__ == '__main__': monitor = Monitor() print(f'monitor: {monitor}') match monitor: case (1440, 900): print("匹配到横向分辨率: (1440, 900)") case (900, 1440): print("匹配到纵向分辨率: (900, 1440)")
说明
添加__match_args__ = ('Width', 'Height')后,match case中的元组模式会自动提取实例的Width和Height属性值进行匹配,完全符合需求。测试时,当显示器旋转导致分辨率切换,match语句会正确命中对应的分支。
内容的提问来源于stack exchange,提问作者phpjunkie
相关产品推荐
相关产品推荐

