私はPythonのメタプログラミングで少し演奏しています。インスタンス作成後に上書きされた__repr__
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
私はメタクラスFormMetaClass
を持ってForm
を持っています。 代わりのコンストラクタを使用するには、@classmethod
を使用しています。 instance
を作成します。これはこれまでのところうまくいくようです。
__repr__
(または__str__
を同じ意味で使用しています)とは何も動作しません。 MyForm()
でインスタンスを作成すると、すべて問題ありません。 @classmethod
経由でインスタンスを作成すると、「デフォルト」の実装が行われます。
Thomas Junk
を期待したが、私は
はあなたが私にヒントを与えることができる<class '__main__.MyForm'>
を取得し、私が何を望むのですか?
おそらく 'field.String()'と 'field.Integer()'オブジェクトは 'FieldDescriptor'インスタンスですか?私はあなたの問題を再現できるかどうかを確認しようとしていますが、これはそれらのオブジェクトが欠落している[mcve]ではありません。 –
ディスクリプタが追加されました。 –
私はディスクリプタなしで既にそれを再現することができます。 –