在尝试使用愚蠢的东西让我的 str 方法在Enum成员上正常工作时,我发现了一些我并不理解的行为。我知道以下实现是错误的,但我不知道它为什么会这样做。
考虑以下课程:
from aenum import Enum, AutoValue
class MyEnum(str, Enum, settings=AutoValue, init="value data1 data2"):
__str__ = lambda self: self
def __new__(cls, name, *args, **kwargs):
member = str.__new__(cls)
member._value_ = name
return member
@staticmethod
def _generate_next_value_(name, *args, **kwargs):
return (name,) + args
member1 = 1, 2
member2 = 3, 4
在导入时,这可以执行。 MyEnum.member1.data1 == 1
和MyEnum.member1.data2 == 2
。但是,当我调用str(MyEnum.member1)
时,会抛出一个异常,说“缺少'data2'的值”。我在这里查看了代码,似乎正在调用MyEnum.member1.__str__().__init__(MyEnum.member1.__str__())
。我不是肯定的是通话路径,但那是结果。由于MyEnum.__init__ is Enum.__init__
我们正在使用AutoValue,因此 init 方法需要两个参数。它正在尝试设置member1.data1 = member1
,而member1.data2
没有值。
要明确,我知道正确的解决方案是将__str__
方法实现为__str__ = str.__str__
。但是,由于isinstance(MyEnum.member1, str) == True
和 str 需要返回一个str ..我不清楚为什么上面的实现会表现如何。
__init__
?self
是不够的,因为self
是str
?__new__
和_generate_next_value_
方法,在导入TypeError
时会抛出str() argument 2 must be str, not int
(... / aenum / 初始化的.py:1302)。 答案 0 :(得分:1)
在对象上调用str
的行为类似于调用任何其他类型:它在您的对象上调用str.__new__
,然后如果结果是str
的实例,则调用{{1}结果。
__init__
调用您的str.__new__
方法,该方法返回__str__
。由于返回值是MyEnum
的实例,因此下一步是调用str
方法。那是意外的__init__
来电的来源。
答案 1 :(得分:1)
@ user2357112拥有它的权利。
详细说明你的观点:
- 为什么返回
醇>self
是不够的,因为self
是str
?
self
不是str
,它是MyEnum
,它是str
子类 - 拥有它自己的__init__
子类str
1}},然后被调用。 __init__
类没有UserSchema.pre('save', (next) => {
console.log('Pre-Save Hash has fired.')
let user = this;
bcrypt.genSalt(10, (err, salt) => {
if (err) console.error(err);
bcrypt.hash(user.password, salt, (err, hash) => {
user.password = hash;
next();
});
});
});
方法。