(Samuel Colvin)
See this discussion.
# in a library or the std library...
class BaseModel: # could be a decorator, same potential problem
def __init__(self, **kwargs):
magic(self, kwargs)
fields: list[FieldInfo] = ...
def json(self):
"""return a JSON representation of the object"""
# in user code...
class Request(BaseModel):
method: str
path: str
fields: Optional[MultiDict] # form data - ERROR!!!
json: Optional[dict] # object from decoding body - ERROR!!!
Affects:
- dataclasses
- namedtuple
- validation/parsing libraries like attrs, pydantic, marshmallow, etc.
- ORMs like sqlalchemy, django, etc.
(in order rough order of how easy they are now)
e.g. mylibrary.json(model)
This is currently used by: attrs, dataclasses ...
Disadvantage:
- less ergonomic
- harder for IDE to help
- steeper learning curve
- IMHO ugly
e.g. model._json()
Currently used by NamedTuple.
Disadvantage:
- encourages use of
_
private methods - pycharm complains
- hard to distinguish between these methods and really private methods
e.g. model.__json__()
Used a bit by pydantic.
Disadvantage:
- often looks "even more private" to new users
- again introduces bad habits
e.g. model.object.json()
Used (sort of) by django model_instance.objects.whatever
.
Disadvantage:
- harder to add new methods as a user
- slower
- again IDE might not be able to help
Suggested by Guido - as with thing.__len__()
and len(thing)
.
Also __replace__
used by replace(model)
was suggested.
Disadvantage:
- This might work for common methods like
__len__
and__fields__
, but not all methods - Same problems as "use module level methods" above
e.g. model['json']
to get the field/value, then model.json()
to access the function.
Disadvantage: breaks the idea of fields as attributes, more typing, unintuitive.
e.g. model.model_json()
.
Then prevent that prefix model_
in fields.
e.g. model.$json()
Disadvantage: everyone else seems to hate this idea.
This is not the big change it might seem like: lots of exotic unicode characters are already allowed in identifiers.
This is used by javascript (for jquery).
e.g. model.ᐅjson()
actually "works", though using it is a terrible idea in reality.
e.g. model::json()
Most concise and (arguably) clear solution.
Disadvantage:
- bigger change
- Makes the language more complicated