41

Could anybody explain whether it is safe to reinitialize an object by calling "self.init(". as shown in the following simplified example?

The reason i'm asking is that i couldn't find this method neither in several python books nor in internet. There are some who suggest to list all attributes and set them to initial value one by one. Basically i want to set my object to initial state after it has finished some tasks.

class Book(object): def __init__(self,name,author): self.name = name self.author = author self.copies = 5 def reset(self): self.__init__(self.name,self.author) def incrementCopy(self): self.copies += 1 Kite = Book('kite runner','khaled hosseini') print 'initial number of copies:', Kite.copies Kite.incrementCopy() Kite.incrementCopy() Kite.incrementCopy() print '3 copies are added:', Kite.copies Kite.reset() print 'number of copies are reinitialized', Kite.copies initial number of copies: 5 3 copies are added: 8 number of copies are reinitialized 5 
2
  • 2
    Why can't you do that in reset function itself, after you will have to pass the initial values again? self.name and self.author accesses the current value, not the initial. Commented Oct 26, 2012 at 17:02
  • self.name and self.author are not going to be changed, they can be ignored in this example. My question is about self.__init__ part. I didn't quite understand your question. What do you mean by "that"? Commented Oct 26, 2012 at 17:09

3 Answers 3

42

The only thing special about __init__ is that it is called automatically when an instance is created. Other than that it is a normal method, and it is safe to use it to set your object back to its initial state.

That being said, just because it is safe doesn't mean it is a good idea. Other people looking at your code might be confused by it, and it isn't difficult to do everything in a reset method (that __init__ can even call) to be more explicit about how the method is being used.

Sign up to request clarification or add additional context in comments.

Comments

33

I would consider it a very bad practice - you should not __init__ manually (unless calling __init__ of the parent class). Also, passing object's data back to __init__ is somewhat strange.

Why not something like this:

class Book(object): def __init__(self,name,author): self.name = name self.author = author self.reset() def reset(self): self.copies = 5 

3 Comments

+1. The standard solution (not just in Python, but in most languages with constructors) is to factor out the code needed by both the constructor and the regular function(s).
Only problem with this is I get code lint warnings: "Instance attribute copies defined outside of init"
yeah, recommended way seems to be to create all the attributes in __init__, frankly speaking I prefer to ignore it and avoid duplication.
7

I consider is not unsafe, I have used it and nothing strange happens in the memory, but take into account that attributes defined in other methods will not be reset. Consider for example:

class Dummy: def __init__(self): self.x = 4 def plus_one(self): self.x += 1 def define_other_variables(self): self.y = 3 def reset(self): self.__init__() D = Dummy() print(D.x) # 4 # print(D.y) will raise an AttributeError D.plus_one() D.plus_one() # D.y do not exist D.define_other_variables() # D.y exist print(D.x) # 6 D.reset() print(D.x) # 4 print(D.y) # 3, still exist!! 

Then, just remember to define every object in the init function. you could consider bad practice for this reason but I still think is elegant.

Comments