Python Enum with exception: TypeError: Attempted to reuse key:
Python Enum with exception: TypeError: Attempted to reuse key:
我试图在失败时重新定义枚举,但随后出现错误。
我的代码如下所示:
from enum import Enum
class FooEnum(Enum):
try:
foo = 3/0
except Exception as my_exception_instance:
print('An error occurred:', my_exception_instance)
foo=0
目标是 3/0
将引发异常,然后重新定义 foo
。
但是,当我按原样 运行 显示打印消息时,会抛出另一个错误,这对我来说没有意义。这是输出和堆栈跟踪:
An error occurred: division by zero
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-10-489d2391f28b> in <module>
1 from enum import Enum
2
----> 3 class FooEnum(Enum):
4 try:
5 foo = 3/0
<ipython-input-10-489d2391f28b> in FooEnum()
6 except Exception as my_exception_instance:
7 print('An error occurred:', my_exception_instance)
----> 8 foo=0
/usr/lib/python3.6/enum.py in __setitem__(self, key, value)
90 elif key in self._member_names:
91 # descriptor overwriting an enum?
---> 92 raise TypeError('Attempted to reuse key: %r' % key)
93 elif not _is_descriptor(value):
94 if key in self:
TypeError: Attempted to reuse key: 'my_exception_instance'
消除此错误的唯一方法是在捕获异常时删除异常的用法:
from enum import Enum
class FooEnum(Enum):
try:
foo = 3/0
except:
print('An error occurred')
foo=0
然后输出:An error occurred
我正在使用 python 3.6.9
编辑
以下代码更接近我的用例:
import tensorflow as tf
from enum import Enum
class VisualModels(Enum):
try:
MobileNet = tf.keras.applications.MobileNetV2
except Exception as e:
print(f'MobileNetV2 Not found, using MobileNet instead. Error: {e}.')
MobileNet = tf.keras.applications.MobileNet
# more models are defined similarly
发生这种情况的原因是:
_EnumDict
跟踪所有使用过的名字
_EnumDict
认为 my_exception_instance
应该是会员
- Python 在离开
except
子句时清除 as
变量
- 通过将
None
分配给 my_exception_instance
(然后删除变量)
- 导致
_EnumDict
认为密钥被重复使用
一种解决方法(从 Python 3.7 开始)是将 my_exception_instance
添加到 _ignore_
1 属性:
class FooEnum(Enum):
_ignore_ = 'my_exception_instance'
try:
foo = 3/0
except Exception as my_exception_instance:
print('An error occurred:', my_exception_instance)
foo=0
另一种解决方法是使 my_exception_instance
成为全局的:
class FooEnum(Enum):
global my_exception_instance
try:
foo = 3/0
except Exception as my_exception_instance:
print('An error occurred:', my_exception_instance)
foo=0
最后,如果您不想在枚举正文中使用 try/except:
class FallbackEnum(Enum):
def __new__(cls, *values):
# first actual value wins
member = object.__new__(cls)
fallback = False
for v in values:
try:
member._value_ = eval(v)
break
except Exception as e:
print('%s error: %s' % (v, e))
fallback = True
continue
else:
# never found a value
raise ValueError('no valid value found')
# if we get here, we found a value
if fallback:
# if the first value didn't work, print the one we did use
print(' using %s' % v)
return member
并在使用中:
>>> class FooEnum(FallbackEnum):
... foo = '3/0', '0'
...
3/0 error: division by zero
using 0
>>> list(FooEnum)
[<FooEnum.foo: 0>]
1 如果卡在 Python 3.6.
可以使用 aenum
披露:我是 Python stdlib Enum
, the enum34
backport, and the Advanced Enumeration (aenum
) 库的作者。
我试图在失败时重新定义枚举,但随后出现错误。
我的代码如下所示:
from enum import Enum
class FooEnum(Enum):
try:
foo = 3/0
except Exception as my_exception_instance:
print('An error occurred:', my_exception_instance)
foo=0
目标是 3/0
将引发异常,然后重新定义 foo
。
但是,当我按原样 运行 显示打印消息时,会抛出另一个错误,这对我来说没有意义。这是输出和堆栈跟踪:
An error occurred: division by zero
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-10-489d2391f28b> in <module>
1 from enum import Enum
2
----> 3 class FooEnum(Enum):
4 try:
5 foo = 3/0
<ipython-input-10-489d2391f28b> in FooEnum()
6 except Exception as my_exception_instance:
7 print('An error occurred:', my_exception_instance)
----> 8 foo=0
/usr/lib/python3.6/enum.py in __setitem__(self, key, value)
90 elif key in self._member_names:
91 # descriptor overwriting an enum?
---> 92 raise TypeError('Attempted to reuse key: %r' % key)
93 elif not _is_descriptor(value):
94 if key in self:
TypeError: Attempted to reuse key: 'my_exception_instance'
消除此错误的唯一方法是在捕获异常时删除异常的用法:
from enum import Enum
class FooEnum(Enum):
try:
foo = 3/0
except:
print('An error occurred')
foo=0
然后输出:An error occurred
我正在使用 python 3.6.9
编辑 以下代码更接近我的用例:
import tensorflow as tf
from enum import Enum
class VisualModels(Enum):
try:
MobileNet = tf.keras.applications.MobileNetV2
except Exception as e:
print(f'MobileNetV2 Not found, using MobileNet instead. Error: {e}.')
MobileNet = tf.keras.applications.MobileNet
# more models are defined similarly
发生这种情况的原因是:
_EnumDict
跟踪所有使用过的名字_EnumDict
认为my_exception_instance
应该是会员- Python 在离开
except
子句时清除as
变量- 通过将
None
分配给my_exception_instance
(然后删除变量) - 导致
_EnumDict
认为密钥被重复使用
- 通过将
一种解决方法(从 Python 3.7 开始)是将 my_exception_instance
添加到 _ignore_
1 属性:
class FooEnum(Enum):
_ignore_ = 'my_exception_instance'
try:
foo = 3/0
except Exception as my_exception_instance:
print('An error occurred:', my_exception_instance)
foo=0
另一种解决方法是使 my_exception_instance
成为全局的:
class FooEnum(Enum):
global my_exception_instance
try:
foo = 3/0
except Exception as my_exception_instance:
print('An error occurred:', my_exception_instance)
foo=0
最后,如果您不想在枚举正文中使用 try/except:
class FallbackEnum(Enum):
def __new__(cls, *values):
# first actual value wins
member = object.__new__(cls)
fallback = False
for v in values:
try:
member._value_ = eval(v)
break
except Exception as e:
print('%s error: %s' % (v, e))
fallback = True
continue
else:
# never found a value
raise ValueError('no valid value found')
# if we get here, we found a value
if fallback:
# if the first value didn't work, print the one we did use
print(' using %s' % v)
return member
并在使用中:
>>> class FooEnum(FallbackEnum):
... foo = '3/0', '0'
...
3/0 error: division by zero
using 0
>>> list(FooEnum)
[<FooEnum.foo: 0>]
1 如果卡在 Python 3.6.
可以使用aenum
披露:我是 Python stdlib Enum
, the enum34
backport, and the Advanced Enumeration (aenum
) 库的作者。