I'm trying to replicate mongoengine functionality that lets you define field objects that can be used like normal python objects in the code.
My idea is to create a FieldHolder
class that contains the value and (de)serialization logic, and a Document
object with overridden __setattr__
and __getattribute__
methods.
In my code draft, if I set x.h
to some value, this value gets correctly assigned to x.h._value
. When I get x.h
, I correctly get x.h._value
.
However, I would also like get h
as a FieldHolder
object and not as its value. I have tried using object.__getattribute__
(inside serialize
method), but I'm still getting h._value
(object.__getattribute__(self, 'h')
returns abc
). What am I doing wrong? Thanks
class FieldHolder:
_value = None
# Some serialization and deserialization methods
class Document(object):
h = FieldHolder()
def __setattr__(self, key, value):
attr = getattr(self, key, None)
if attr is not None and isinstance(attr, FieldHolder):
attr._value = value
else:
super().__setattr__(key, value)
def __getattribute__(self, key):
val = super().__getattribute__(key)
if isinstance(val, FieldHolder):
return val._value
else:
return val
def serialize(self):
res = {}
for name, value in vars(self).items():
obj = object.__getattribute__(self, name) # not working as expected
if isinstance(obj, FieldHolder):
res[name] = value
return res
x = Document()
x.h = "abc" # h._value is now "abc"
print(x.h) # prints "abc"
s = x.serialize() # should return {'h': 'abc'} but returns {}
print(s)