2015-09-30 3 views
-1

У меня есть собственный класс Python, который расширяет встроенный тип «dict».Пользовательский словарь и модуль JSON в Python

######################################################################## 
class ServiceParametersNew(dict): 
    """""" 
    _allowed = ['maxRecordCount', 'tables', 
       'allowGeometryUpdates', 'supportsDisconnectedEditing', 
       'description', 'name', 'xssPreventionInfo', 
       'hasStaticData', 'capabilities', 'copyrightText', 
       'currentVersion', 'size', 'hasVersionedData', 
       'units', 'syncEnabled', 'supportedQueryFormats', 
       'editorTrackingInfo', 'serviceDescription'] 
    _editorTrackingInfo = { 
     "enableEditorTracking": True, 
     "enableOwnershipAccessControl": False, 
     "allowOthersToUpdate": True, 
     "allowOthersToDelete": True} 
    _xssPreventionInfo = { 
     "xssPreventionEnabled": True, 
     "xssPreventionRule": "InputOnly", 
     "xssInputRule": "rejectInvalid"} 
    _tables = [] 
    #---------------------------------------------------------------------- 
    def __str__(self): 
     """returns object as string""" 
     val = {} 
     for a in self._allowed: 
      if a in self.__dict__: 
       val[a] = self.__getitem__(a) 
     val['table'] = self._tables 
     val['xssPreventionInfo'] = self._xssPreventionInfo 
     val['editorTrackingInfo'] = self._editorTrackingInfo 
     return json.dumps(val) 
    #---------------------------------------------------------------------- 
    def __getitem__(self, key): 
     if key.lower() in [a.lower() for a in self._allowed]: 
      return self.__dict__[key] 
     raise Exception("Invalid parameter requested") 
    #---------------------------------------------------------------------- 
    def __setitem__(self, index, value): 
     self.__dict__[index] = value 
    #---------------------------------------------------------------------- 
    @property 
    def xssPreventionInfo(self): 
     """gets the xssPreventionInfo""" 
     return self._xssPreventionInfo 
    #---------------------------------------------------------------------- 
    @property 
    def editorTrackingInfo(self): 
     """gets the editorTrackingInfo settings""" 
     return self._editorTrackingInfo 
    #---------------------------------------------------------------------- 
    def updateXssPreventionInfo(self, xssPreventionEnabled=True, 
           xssPreventionRule="InputOnly", 
           xssInputRule="rejectInvalid"): 
     """updates the xss prevention information""" 
     self._xssPreventionInfo = { 
      "xssPreventionEnabled": True, 
      "xssPreventionRule": "InputOnly", 
      "xssInputRule": "rejectInvalid" 
     } 
    #---------------------------------------------------------------------- 
    def updateEditorTrackingInfo(self, 
           enableEditorTracking=True, 
           enableOwnershipAccessControl=False, 
           allowOthersToUpdate=True, 
           allowOthersToDelete=True 
           ): 
     """updates the editor tracking information""" 
     self._editorTrackingInfo = { 
      "enableEditorTracking": enableEditorTracking, 
      "enableOwnershipAccessControl": enableOwnershipAccessControl, 
      "allowOthersToUpdate": allowOthersToUpdate, 
      "allowOthersToDelete": allowOthersToDelete 
     } 

Класс в основном собирается проверить, является ли значение в допустимом словаре, если она есть, она вводится в стоимость.

Я понял, что, поскольку унаследовал от dict, я мог бы использовать json.dumps(<object>), чтобы сбрасывать класс в строковое значение.

Должен ли я переопределить другую функцию, чтобы получить эту работу?

+1

Вы ищете 'json.dumps (yourobject .__ ДИКТ __)'? –

+0

Вам нужно вызвать __dict__ на объект со словарным объектом a = {}, вы можете просто сделать json.dumps (a). –

+0

Вы попробовали? Он работает очень хорошо (при условии, что вы исправите тот факт, что класс, как указано, в настоящее время не работает вообще, например, отсутствует что-либо, что устанавливает '_allowed'). –

ответ

1

Вы неправильно понимаете __dict__ - это не место для данных dict, это место, где атрибуты хранятся для большинства классов. Например:

>>> class A(dict): 
... def __init__(self): 
...  dict.__init__(self) 
...  self.x = 123 
... 
>>> a=A() 
>>> a.__dict__ 
{'x': 123} 

Так, a.__dict__['x'] часто (но не всегда) такой же, как a.x.

Как правило: не использовать __dict__, если вы действительно не любите темные запрещенные маги..

Чтобы заставить ваш класс работать и успешно сериализоваться в json, просто используйте dict.__getitem__, как и любой обычный вызов класса суперкласса.

class ExtendedDict(dict): 
    _allowed = ['a', 'b'] 
    def __getitem__(self, key): 
     if key.lower() in [a.lower() for a in self._allowed]: 
      # Just call superclass method 
      return dict.__getitem__(self, key) 
     raise Exception("Invalid parameter requested") 

d = ExtendedDict() 
d['a'] = 1 
d['b'] = 2 
import json, sys 
sys.stdout.write(json.dumps(d)) 

Это будет печатать:

{"a": 1, "b": 2} 
+0

Спасибо, я проверю это, должен ли я также реализовать __setattr __() также как лучшую форму? Кроме того, следует ли использовать super() вместо наследования? Я только спрашиваю о super(), потому что независимо от того, сколько раз я смотрю супер, рассматриваю super() презентацию, я все еще запутался. –

+0

'super' не требуется, если вы просто подклассифицируете' dict'. Будь проще. Что касается '__setitem__', возможно, вы тоже этого захотите. – alexanderlukanin13

+0

спасибо, очень полезно. –

Смежные вопросы