我正在玩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
答案 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