如何创建含pathlib.Path混入的Enum?解决AttributeError: _flavour报错
问题
尝试创建一个混入pathlib.Path的枚举,编写了以下最小可复现代码:
import enum, pathlib class Test(pathlib.Path, enum.Enum): path1 = pathlib.Path('/path1') path2 = pathlib.Path('/path2')
运行后出现AttributeError: _flavour错误,完整报错信息如下:
1 import enum, pathlib ----> 2 class Test(pathlib.Path, enum.Enum): 3 path1 = pathlib.Path('/path1') 4 path2 = pathlib.Path('/path2') File ~/anaconda3/envs/main/lib/python3.9/enum.py:288, in EnumMeta.__new__(metacls, cls, bases, classdict, **kwds) 286 enum_member._value_ = value 287 else: --> 288 enum_member = __new__(enum_class, *args) 289 if not hasattr(enum_member, '_value_'): 290 if member_type is object: File ~/anaconda3/envs/main/lib/python3.9/pathlib.py:1082, in Path.__new__(cls, *args, **kwargs) 1080 if cls is Path: 1081 cls = WindowsPath if os.name == 'nt' else PosixPath --> 1082 self = cls._from_parts(args, init=False) 1083 if not self._flavour.is_supported: 1084 raise NotImplementedError("cannot instantiate %r on your system" 1085 % (cls.__name__,)) File ~/anaconda3/envs/main/lib/python3.9/pathlib.py:707, in PurePath._from_parts(cls, args, init) 702 @classmethod 703 def _from_parts(cls, args, init=True): 704 # We need to call _parse_args on the instance, so as to get the 705 # right flavour. 706 self = object.__new__(cls) --> 707 drv, root, parts = self._parse_args(args) 708 self._drv = drv 709 self._root = root File ~/anaconda3/envs/main/lib/python3.9/pathlib.py:700, in PurePath._parse_args(cls, args) 695 else: 696 raise TypeError( 697 "argument should be a str object or an os.PathLike " 698 "object returning str, not %r" 699 % type(a)) --> 700 return cls._flavour.parse_parts(parts) File ~/anaconda3/envs/main/lib/python3.9/enum.py:429, in EnumMeta.__getattr__(cls, name) 427 return cls._member_map_[name] 428 except KeyError: --> 429 raise AttributeError(name) from None AttributeError: _flavour
原因与解决方案
错误原因
pathlib.Path和enum.Enum的继承逻辑存在本质冲突:
- 枚举的元类
EnumMeta在创建类时,会尝试用当前枚举类作为构造器去实例化成员值,而非直接使用成员值本身。 pathlib.Path是依赖类属性_flavour处理系统路径逻辑的工厂类,但枚举类初始化过程中并未正确初始化该属性,导致访问cls._flavour时触发枚举的属性查找逻辑,最终抛出AttributeError。
正确实现方式
不要直接让枚举类继承pathlib.Path,而是将Path对象作为枚举成员的值存储,以下是两种可行方案:
方案1:直接存储Path对象,通过.value访问
这是最简洁的实现方式,直接利用枚举存储Path实例,使用时通过.value调用路径方法:
import enum import pathlib class Test(enum.Enum): path1 = pathlib.Path('/path1') path2 = pathlib.Path('/path2') # 使用示例 print(Test.path1.value.exists())
方案2:让枚举实例代理Path方法
如果不想每次都写.value,可以自定义枚举类,通过__getattr__代理Path对象的所有属性和方法:
import enum import pathlib class PathEnum(enum.Enum): def __getattr__(self, name): return getattr(self.value, name) class Test(PathEnum): path1 = pathlib.Path('/path1') path2 = pathlib.Path('/path2') # 使用示例 print(Test.path1.exists())
内容的提问来源于stack exchange,提问作者alex
相关产品推荐
相关产品推荐

