Python 派生枚举缺少必需的位置参数
Python derived enum missing required positional argument
我正在尝试定义一个对象值枚举,但我 运行 在 enum_member.__init__(*args)
中出现“缺少 1 个必需的位置参数”错误
我的代码的一个基本示例,在 the documentation from enum 之后,我们称它为 problem.py
,它是在 upper.py
中导入的
import enum
class test(object):
def __init__(self, par1, par2):
# do stuff with the parameters and assign to object fields
# more object methods
class testlist(test, enum.Enum):
A = test(1,2)
B = test(3,4),
# a few more of these
导入定义了这些 类 的模块时,出现以下错误(已编辑以匹配示例):
File "upper.py", line 14, in <module>
from problem import test
File "problem.py", line 75, in <module>
class testlist(test, enum.Enum):
File "/usr/lib/python3.8/enum.py", line 252, in __new__
enum_member.__init__(*args)
TypeError: __init__() missing 1 required positional argument: 'par2'
我猜我误解了派生枚举的工作原理,但从文档中我无法弄清楚我是如何遗漏一个参数的。
(编辑)
目标是让 testlist
值表现为 test
对象,它还定义了一些方法并覆盖了算术运算符,所以我可以做到,例如 testlist.A + testlist.B
。枚举不是绝对必要的,但它便于迭代,并且比将它们作为模块中的全局变量更好地对值进行分组。
请注意枚举对于 __new__
和 __init__
有自己的方式,在您的情况下,您不需要将 test
作为 parent class.如果您确实需要,请按照文档 https://docs.python.org/3/library/enum.html#when-to-use-new-vs-init
没有 test
class 作为你的 parent class,它会工作
import enum
class test:
def __init__(self, par1, par2):
print(self, par1, par2)
class testlist(enum.Enum):
A = test(1, 2)
B = test(3, 4)
编辑:下面的代码支持 + 运算符
检查输出以了解更多 enum subclassing 是如何工作的。
import enum
class test(object):
def __init__(self, par1, par2):
print(self,':', par1, par2)
self.par1 = par1
self.par2 = par2
def __add__(self, rval):
print("test:", self, "+", rval)
class testlist(test, enum.Enum):
A = (1,2)
B = (3,4)
# a few more of these
def __new__(cls, par1, par2):
obj = object.__new__(cls)
obj._value_ = test(par1, par2)
return obj
def __init__(self, *args):
print(self.__class__, args)
# call __add__ of `testlist` if exist, otherwise __add__ of `test`
testlist.A + testlist.B
# value is `test` object
testlist.A.value + testlist.B.value
输出
<__main__.test object at 0x7f112f1d7430> : 1 2
<enum 'testlist'> (1, 2)
<__main__.test object at 0x7f112f1f52e0> : 3 4
<enum 'testlist'> (3, 4)
test: testlist.A + testlist.B
test: <__main__.test object at 0x7f112f1d7430> + <__main__.test object at 0x7f112f1f52e0>
旁白:在您的 B = test(3,4),
示例中,最后的逗号不应该出现。
你 运行 的意思是,当你对另一个数据类型进行子类化时,无论你分配给成员名称的是什么,都将传递给子类化类型的 __new__
and/or __init__
.
换句话说,通过从 test
继承,您的 testlist
枚举现在有一个 __init__
,它需要两个参数:一个用于 par1
,一个用于 par2
——但你只提供了一个参数,例如test(1, 2)
。您需要提供的只是 1, 2
:
class testlist(test, enum.Enum):
A = 1, 2
B = 3, 4
# a few more of these
在上面的代码中,A
的值将通过调用 test(1, 2)
.
来计算
另一个可能有帮助的示例:可以使用两个参数调用 int
,第一个是 str
,第二个是解释该字符串的基数。所以:
class Count(IntEnum):
ONE = 1 # value generated by int(1)
TWO = '2' # value generated by int('2')
THREE = '3', 10 # value generated by int('3', 10)
TEN = 'A', 16 # value generated by int('A', 16)
当 list
编辑时:
>>> list(Count)
[<Count.ONE: 1>, <Count.TWO: 2>, <Count.THREE: 3>, <Count.TEN: 10>]
我正在尝试定义一个对象值枚举,但我 运行 在 enum_member.__init__(*args)
我的代码的一个基本示例,在 the documentation from enum 之后,我们称它为 problem.py
,它是在 upper.py
import enum
class test(object):
def __init__(self, par1, par2):
# do stuff with the parameters and assign to object fields
# more object methods
class testlist(test, enum.Enum):
A = test(1,2)
B = test(3,4),
# a few more of these
导入定义了这些 类 的模块时,出现以下错误(已编辑以匹配示例):
File "upper.py", line 14, in <module>
from problem import test
File "problem.py", line 75, in <module>
class testlist(test, enum.Enum):
File "/usr/lib/python3.8/enum.py", line 252, in __new__
enum_member.__init__(*args)
TypeError: __init__() missing 1 required positional argument: 'par2'
我猜我误解了派生枚举的工作原理,但从文档中我无法弄清楚我是如何遗漏一个参数的。
(编辑)
目标是让 testlist
值表现为 test
对象,它还定义了一些方法并覆盖了算术运算符,所以我可以做到,例如 testlist.A + testlist.B
。枚举不是绝对必要的,但它便于迭代,并且比将它们作为模块中的全局变量更好地对值进行分组。
请注意枚举对于 __new__
和 __init__
有自己的方式,在您的情况下,您不需要将 test
作为 parent class.如果您确实需要,请按照文档 https://docs.python.org/3/library/enum.html#when-to-use-new-vs-init
没有 test
class 作为你的 parent class,它会工作
import enum
class test:
def __init__(self, par1, par2):
print(self, par1, par2)
class testlist(enum.Enum):
A = test(1, 2)
B = test(3, 4)
编辑:下面的代码支持 + 运算符 检查输出以了解更多 enum subclassing 是如何工作的。
import enum
class test(object):
def __init__(self, par1, par2):
print(self,':', par1, par2)
self.par1 = par1
self.par2 = par2
def __add__(self, rval):
print("test:", self, "+", rval)
class testlist(test, enum.Enum):
A = (1,2)
B = (3,4)
# a few more of these
def __new__(cls, par1, par2):
obj = object.__new__(cls)
obj._value_ = test(par1, par2)
return obj
def __init__(self, *args):
print(self.__class__, args)
# call __add__ of `testlist` if exist, otherwise __add__ of `test`
testlist.A + testlist.B
# value is `test` object
testlist.A.value + testlist.B.value
输出
<__main__.test object at 0x7f112f1d7430> : 1 2
<enum 'testlist'> (1, 2)
<__main__.test object at 0x7f112f1f52e0> : 3 4
<enum 'testlist'> (3, 4)
test: testlist.A + testlist.B
test: <__main__.test object at 0x7f112f1d7430> + <__main__.test object at 0x7f112f1f52e0>
旁白:在您的 B = test(3,4),
示例中,最后的逗号不应该出现。
你 运行 的意思是,当你对另一个数据类型进行子类化时,无论你分配给成员名称的是什么,都将传递给子类化类型的 __new__
and/or __init__
.
换句话说,通过从 test
继承,您的 testlist
枚举现在有一个 __init__
,它需要两个参数:一个用于 par1
,一个用于 par2
——但你只提供了一个参数,例如test(1, 2)
。您需要提供的只是 1, 2
:
class testlist(test, enum.Enum):
A = 1, 2
B = 3, 4
# a few more of these
在上面的代码中,A
的值将通过调用 test(1, 2)
.
另一个可能有帮助的示例:可以使用两个参数调用 int
,第一个是 str
,第二个是解释该字符串的基数。所以:
class Count(IntEnum):
ONE = 1 # value generated by int(1)
TWO = '2' # value generated by int('2')
THREE = '3', 10 # value generated by int('3', 10)
TEN = 'A', 16 # value generated by int('A', 16)
当 list
编辑时:
>>> list(Count)
[<Count.ONE: 1>, <Count.TWO: 2>, <Count.THREE: 3>, <Count.TEN: 10>]