1

In Python, what is standard/commonly used way to reset class to "default state"? For example, before loading something to class you might want to reset existing data.

For example, check out self.clear() method below:

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))

This approach seems to do the job, but I wonder if there is another way to do it.


The other question (which does not have accepted answers) seems to cover diferrent problem - it has couple of numerical fields that needs to be all initialized with zero, while in this scenario there are bunch of members that have different default state - dictionaries, arrays, numbers, strings, etc.

So it was less about "how do I iterate through class attributes" and more about: "does python have commonly used paradigm for this particular situation". Accessing attributes by their names using strings doesn't seem quite right.

Community
  • 1
  • 1
SigTerm
  • 26,089
  • 6
  • 66
  • 115
  • 3
    Python's `HTMLParser` uses `reset()`, so that's one data point, but in general, I'd argue that you should just make a new instance rather than reusing an old one. Usually, constructing new instances is not such a bottleneck that it needs to be avoided. – kindall Mar 21 '15 at 00:59
  • @michaelpri: I'd like to point out that the other question does not have accepted answer. None of the suggested answers seems to be alternative technique . – SigTerm Mar 21 '15 at 01:25
  • @kindall: Your suggestion is reasonable, but it doesn't apply in all cases. If object is supposed to stay alive for a while and adjust its contents in response to one of its field changing, "new instances" might not be applicable. IMO. – SigTerm Mar 21 '15 at 01:28
  • If you changed `SERIAIZABLE_ATTRIBUTES` to a `dict` containing the attributes and their default values, you could 1) avoid initializing a temporary instance to copy the attributes, and 2) initialize the object by calling `clear` as well, in which case there's no code duplication. – Patrick McLaren Mar 21 '15 at 01:43
  • 1
    @SigTerm - I agree it doesn't apply in all cases, hence my use of weasel words like "in general" and "usually." :-) – kindall Mar 21 '15 at 16:28

1 Answers1

1

If you changed SERIAIZABLE_ATTRIBUTES to a dict containing the attributes and their default values, you could avoid initializing a temporary instance to copy the attributes, and initialize the object by calling clear as well, in which case there's no code duplication.

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())
Patrick McLaren
  • 978
  • 10
  • 22
  • Think you want a `self.clear()` there... and also not sure about forcing the types to be callable, but otherwise, not bad :) – Jon Clements Mar 21 '15 at 02:06
  • Smart solution, I give you that. Thought at this point it looks a lot like explicitly declaring variable type and using default constructor in languages like C++. :-\ – SigTerm Mar 21 '15 at 02:32
  • 1
    One nice thing about this solution is that the values in the dictionaries don't necessarily need to be types. Any callable object will work. So, you could use a `lambda` expression to specify something other than a default-contstructed object (e.g. `SERIALIZABLE_ATTRIBUTES = { "list_of_nums": lambda: [1,2,3] }`). – Blckknght Mar 21 '15 at 02:58