实例创建后覆盖__repr__

时间:2016-11-12 18:27:48

标签: python

我正在玩Python元编程。

yarn add lodash  33,42s user 5,72s system 108% cpu 36,203 total

我有class FormMetaClass(type): def __new__(cls, clsname, bases, methods): # Attach attribute names to the descriptors for key, value in methods.items(): if isinstance(value, FieldDescriptor): value.name = key return type.__new__(cls, clsname, bases, methods) class Form(metaclass=FormMetaClass): @classmethod def from_json(cls, incoming): instance = cls() data = json.loads(incoming) for k, v in data.items(): if (not hasattr(instance, k)): raise KeyError("Atrribute not found") instance.__setattr__(k, v) return cls class MyForm(Form): first_name = String() last_name = String() age = Integer() def __repr__(self): return "{} {}".format(self.first_name, self.last_name) def main(): data = json.dumps({'first_name': 'Thomas', 'last_name': 'Junk'}) form = MyForm.from_json(data) print(form) if __name__ == "__main__": main() class FieldDescriptor: def __init__(self, name=None, **opts): self.name = name for key, value in opts.items(): setattr(self, key, value) def __set__(self, instance, value): instance.__dict__[self.name] = value class Typechecked(FieldDescriptor): expected_type = type(None) def __set__(self, instance, value): if not isinstance(value, self.expected_type): raise TypeError('expected ' + str(self.expected_type)) super().__set__(instance, value) class Integer(Typechecked): expected_type = int class String(Typechecked): expected_type = str ,其中有一个元类Form。 要使用替代构造函数,我使用的是FormMetaClass。 我创建了一个@classmethod,到目前为止似乎有效。

无法正常工作的是instance(或__repr__可互换)。 当我通过__str__创建实例时,一切都很好。 当我通过MyForm()创建实例时,有些"默认"实施。

我期待@classmethod,但我得到Thomas Junk

你可以给我一个暗示,我在俯瞰什么?

1 个答案:

答案 0 :(得分:3)

您正在返回该类,而不是新创建的实例:

return cls

所以你返回MyForm,而不是新实例MyForm(),你只需要设置所有属性。而且您确实看到了该类的repr()输出:

>>> form is MyForm
True
>>> print(MyForm)
<class '__main__.MyForm'>

修复很简单,请改为instance

return instance

或者,作为一个完整的方法:

@classmethod
def from_json(cls, incoming):
    instance = cls()
    data = json.loads(incoming)
    for k, v in data.items():
        if (not hasattr(instance, k)):
            raise KeyError("Atrribute not found")
        instance.__setattr__(k, v)
    return instance

此时该方法返回一个实例,一切正常:

>>> isinstance(form, MyForm)
True
>>> print(form)
Thomas Junk