2016-08-23 58 views
0

我有一組python webservices,它們可以通過JSON POSTs獲取數據對象。在我的舊服務中,我有很多樣板可以對每個對象進行序列化和檢查JSON。隨着Python 3.5s新的打字和PEP 484我有這種感覺,可以大大減少。這值得麼?有沒有人有一個很好的解決方案?如何在Python 3.5中從JSONs初始化類時減少樣板文件?

其他信息

我的老樣板看起來像這樣爲每個對象:

class Data: 

    class Nested1: 
     def __init__(self, nested1_flat1): 
      self.nested1_flat1 = nested1_flat1 

     @classmethod 
     def from_jsond(cls, jsond): 
      # jsond : dict of strings, lists and dicts as usually receivied from reading JSON 
      kwargs = {} 
      for key, val in jsond.items(): 
       # lots of code to deal with special objects , e.g. 
       if key=='date' : kwargs[key] = cleverly_build_datetime_from_js_format(val) 
      return cls.__init__(**kwargs) 

    def __init__(self, flat1, nested1): 
     self.flat1 = flat1 
     self.nested1 = nested1 

    @classmethod 
    def from_jsond(cls, jsond): 
     kwargs = {} 
     for key, val in jsond.items(): 
      # lots of code to deal with nested and special objects, e.g. 
      if key=='nested1' : kwargs[key] = Nested1.from_jsond(val) 
     return cls.__init__(**kwargs) 

我設法減少它歸結爲以下

@from_jsond 
class Data: 

    @from_jsond 
    class Nested1: 

     @auto_assign 
     @beartype 
     def __init__(self, nested1_flat1: str): 
      pass 

    @auto_assign 
    @beartype 
    def __init__(self, flat1: str, nested1: Nested1) 
     pass 

這裏我用的片段爲@auto_assign@beartype和我自己的from_jsond。

import inspect 
from typing import Any 

_JSON_READABLE = [str, list, dict, Any] 

def _from_jsond(cls, json_dict): 
    ''' 
    Entity specific conversion of string dictionary to entity. 
    The json_dict is a dict of string, lists and other dicts as typically encoded in a JSON. 
    ''' 
    kwargs = {} 
    init_parameters = inspect.signature(cls.__init__).parameters 
    for key, val in json_dict.items(): 
     if key in init_parameters.keys(): 
      if init_parameters[key].annotation in _JSON_READABLE: 
       kwargs[key] = val 
      else: 
       if hasattr(init_parameters[key].annotation, 'from_jsond'): 
        kwargs[key] = init_parameters[key].annotation.from_jsond(val) 
       else: 
        raise TypeError('No method to unserialize type "' + init_parameters[key].annotation.__name__ + '"') 
     else: 
      raise AttributeError('Class "' + cls.__name__ + '" does not accept attribute "' + key + '"') 
    return cls(**kwargs) 

def from_jsond(cls): 
    ''' Wrapper to add _from_jsonlike to cls as classmethod ''' 

    cls.from_jsonlike = classmethod(_from_jsond) 
    return cls 

繼承可能最有可能進一步減少它,但我不知道是否值得的麻煩和足夠穩定。意見和經驗,歡迎:)

回答

1

不,PEP 484和類型提示一般不會幫助你減少樣板。

最簡單的解釋是,蟒蛇運行時間不PEP 484 Python解釋器執行類型提示只,以確保語法是正確的認識,沒有不確定姓名等

因此,沒有辦法通過使用類型提示來有意義地改變程序的運行時行爲。

只有在您執行解釋程序之前單獨處理類型提示才能驗證您的類型是否正確。沒有信息從該分析流向python解釋器。

當然,您可以在運行時自己閱讀源代碼的類型註釋,然後按照自己的意願去做。但是這顯然不是你要問的,因爲爲了用這種方法做任何有用的事情,你必須編寫許多相當複雜的代碼。