2016-07-13 20 views
2

Ich mache einen Encoder für die Konvertierung von Python-Objekten in JSON und bei der Recherche sehe ich viele Lösungen, die eine default Methode enthalten. Ich bin kein Experte in Python, aber definitiv auch kein Anfänger, und ich frage mich, ob ich irgendwie vermisste, dass es eine default Methode gibt, die automatisch ausgeführt wird, wenn eine Klasse aufgerufen wird. Oder, ist das nur, weil ich von der JSONEcoder Klasse geerbt habe (die eine Standardmethode hat, und ich jetzt gerade überschreibe)? Kann jemand klären? Und wenn ja, ist es im Prinzip das gleiche wie die Methode?default() Methode in Python

By the way, mein Encoder sieht wie folgt aus, wenn Sie eher ein visueller benötigen:

class ComplexEncoder(json.JSONEncoder): 
    def default(self, obj): 
     if isinstance(obj, my_custom_object): 
      return str(obj) 
     return json.JSONEncoder.default(self, obj) 

Antwort

3

JSONEncoder hat eine default Methode, die aufgerufen wird, wenn er nicht weiß, wie ein bestimmtes Objekt in gültige zu zwingen JSON. Die Standardimplementierung löst nur TypeError aus (weil sie nicht wissen, wie sie den Typ erzwingen). Wenn Sie jedoch überschreiben die Standardmethode, haben Sie eine Chance, ein Objekt zurückgeben, dass der Encoder tut wissen, wie Sie umgehen. Wenn Sie nicht wissen, wie man den Typ, der Eingabe ist (z. B. ist es keine Instanz von my_custom_type), dann sollten Sie entweder raise TypeError selbst, oder rufen Sie die default Methode auf JSONencoder, so dass es den Fehler auslösen kann.

Häufig werden Sie super hier für kooperative Erbe gebraucht:

class ComplexEncoder(json.JSONEncoder): 
    def default(self, obj): 
     if isinstance(obj, my_custom_object): 
      return str(obj) 
     return super(ComplexEncoder, self).default(obj) 

Wenn alle die Encoder-Klassen Sie sind von dieser Form zu bauen, können Sie sie zusammen mischen:

class MySuperEncoder(ComplexEncoder, WidgetEncoder, FooEncoder): 
    pass 

Nun wird ComplexEncoder mit den Dingen umgehen, die es kennt (zB my_custom_object), WidgetEncoder wird die Dinge kodieren, mit denen es umzugehen weiß (wahrscheinlich Widget Instanzen) und so weiter.

2

dir(JSONEncoder) Runnning gibt uns:

['__class__', 
'__delattr__', 
'__dict__', 
'__doc__', 
'__format__', 
'__getattribute__', 
'__hash__', 
'__init__', 
'__module__', 
'__new__', 
'__reduce__', 
'__reduce_ex__', 
'__repr__', 
'__setattr__', 
'__sizeof__', 
'__str__', 
'__subclasshook__', 
'__weakref__', 
'default', # We found our method, let's see what it does 
'encode', 
'item_separator', 
'iterencode', 
'key_separator'] 

Lauf help(JSONEncoder.default) uns gibt:

default(self, o) unbound json.encoder.JSONEncoder method 
    Implement this method in a subclass such that it returns 
    a serializable object for ``o``, or calls the base implementation 
    (to raise a ``TypeError``). 

    For example, to support arbitrary iterators, you could 
    implement default like this:: 

     def default(self, o): 
      try: 
       iterable = iter(o) 
      except TypeError: 
       pass 
      else: 
       return list(iterable) 
      # Let the base class default method raise the TypeError 
      return JSONEncoder.default(self, o) 

So scheint es es so konzipiert, damit Sie Ihre eigenen schreiben, sollten Sie diese Objektunterklasse.

1

Ich denke, dass diese Methode in json.JSONEncoder wie beschrieben here definiert ist. default(o) sollte eine serialisierbare Version des gegebenen Objekts zurückgeben oder es an seine Oberklasse übergeben.

+0

Ja, genau das habe ich auch angefangen zu denken. Ich war mir nicht sicher, ob default() eine Art "magische Methode" war, von der ich nichts wusste. Vielen Dank! – AmericanMade