2015-03-21 5 views
1

В Python, что является стандартным/обычно используемым способом сброса класса в "состояние по умолчанию"? Например, перед загрузкой чего-либо в класс вы можете сбросить существующие данные.Сброс класса по умолчанию

Например, проверить self.clear() метод ниже:

class ConLanguage: 
    SERIALIZABLE_ATTRIBUTES = \ 
     ["roots", "prefixes", "suffixes"...] #list of "important" fields 

    def __init__(self): 
     self.roots = [] 
     self.prefixes = [] 
     self.suffixes = [] 
     ..... 

    def clear(self): # <<--- this method 
     tmp = ConLanguage() 
     for attr in self.SERIALIZEABLE_ATTRIBUTES: 
      setattr(self, attr, getattr(tmp)) 

    def loadFromDict(self, inDict): 
     defaultValues = ConLanguage() 
     for attr in self.SERIALIZABLE_ATTRIBUTES: 
      setattr(self, attr, inDict.get(attr, getattr(defaultValues.attr))) 

    def loads(self, s): 
     self.loadFromDict(json.loads(s)) 

Этот подход, кажется, чтобы сделать работу, но мне интересно, если есть другой способ сделать это.


other question (который не принимаются ответы), кажется, чтобы покрыть diferrent проблему - она ​​имеет несколько числовых полей, которая должна быть инициализированы с нуля, в то время как в этом случае есть куча элементов, которые имеют разные по умолчанию - словари, массивы, числа, строки и т. д.

Значит, это было меньше о том, «как я повторяю атрибуты класса» и больше о: «делает ли python обычно используемой парадигмой для этой конкретной ситуации». Доступ к атрибутам по их именам с помощью строк не кажется вполне правильным.

+3

Питона '' HTMLParser' использует сброс() ', так что одна точка данных, но в целом, я бы утверждать, что вы должны просто сделать новый экземпляр, а не повторное использование старого. Обычно создание новых экземпляров не является таким узким местом, которого нужно избегать. – kindall

+0

@michaelpri: Я хотел бы указать, что другой вопрос не принял ответ. Ни один из предложенных ответов не является альтернативной техникой. – SigTerm

+0

@kindall: Ваше предложение разумно, но оно не применяется во всех случаях. Если объект должен оставаться в живых на некоторое время и настроить его содержимое в ответ на одно из его изменений поля, «новые экземпляры» могут быть неприменимы. ИМО. – SigTerm

ответ

1

Если вы изменили SERIAIZABLE_ATTRIBUTES на dict, содержащий атрибуты и их значения по умолчанию, вы могли бы избежать инициализации временного экземпляра для копирования атрибутов и инициализировать объект, вызывая также ясность, и в этом случае дублирование кода отсутствует.

class Foo: 
    SERIALIZABLE_ATTRIBUTES = { 
    'belongings' : list, 
    'net_worth' : float 
    } 

    def __init__(self): 
    self.clear() 

    def clear(self): 
    for k, v in SERIALIZABLE_ATTRIBUTES.items(): 
     setattr(self, k, v()) 
+0

Подумайте, что вы хотите 'self.clear()' там ... и также не уверены в том, что вы вызываете типы, подлежащие вызову, но в противном случае, неплохо :) –

+0

Умное решение, я вам это даю. Думаю, в этот момент он очень похож на явное объявление типа переменной и использование конструктора по умолчанию в таких языках, как C++. : - \ – SigTerm

+1

Одна из приятных вещей в этом решении заключается в том, что значения в словарях необязательно должны быть типами. Любой вызываемый объект будет работать. Таким образом, вы можете использовать выражение 'lambda' для указания чего-то другого, кроме объекта с по умолчанию (например,' SERIALIZABLE_ATTRIBUTES = {"list_of_nums": lambda: [1,2,3]} '). – Blckknght

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