Generally, we can define __str__ method to make str(obj) return what we want.
But now I want to define my Model object to return a default JSON string when using json.dumps(obj).
Is there any nice way for me to declare a method in the class to do this?
class MyClass:
    ...
    def __json__(self):
        return {'name': self.name, 'age': self.age}
obj = MyClass()
json.dumps(obj) # returns the same as json.dumps(obj.__json__)
                If you only need Python -> JSON, it's simple to write a JSONEncoder class that calls such a method for any object:
class AutoJSONEncoder(JSONEncoder):
    def default(self, obj):
        try:
            return obj._json()
        except AttributeError:
            return JSONEncoder.default(self, obj)
You can then use the class directly AutoJSONEncoder().encode(obj) or through the dumps interface json.dumps(obj, cls=AutoJSONEncoder).
The reverse direction requires at least a list of classes for which to call a _fromjson method.
(Note: __foo__ names are reserved so you shouldn't define them for your own purposes. __bar invokes name mangling, which probably isn't what you want.)
import json
class MyEncoder(json.JSONEncoder):
    """
    JSONEncoder subclass that leverages an object's `__json__()` method,
    if available, to obtain its default JSON representation. 
    """
    def default(self, obj):
        if hasattr(obj, '__json__'):
            return obj.__json__()
        return json.JSONEncoder.default(self, obj)
class MyClass(object):
    name = 'John'
    age = 30
    def __json__(self):
        return {'name': self.name, 'age': self.age}
>>> json.dumps(MyClass(), cls=MyEncoder)
{"age": 30, "name": "John"}
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With