If I need to have a function do some processing in order to initialize multiple of the object's variable (I'm having a hard time coming up with a simple example that doesn't seem weird).
Which of the following patterns is preferable?
class foo( object ):
def __init__(self, bar, bar2):
self.bar = bar
self.baz, self.square_baz = self.func(bar2)
def func(self, bar2):
return self.bar + bar2, bar2 * ba2
Or
class foo( object ):
def __init__(self, bar, bar2):
self.bar = bar
self.func(bar2)
def func(self, bar2):
self.baz = self.bar + bar2
self.square_baz = bar2 * bar2
I feel like in the first pattern, the __init__
constructor and the processing func
are nicely decoupled. And it's easy to tell what variables each instance of foo
will contain. On the other hand, having to return multiple variables from a function to assign them to an object seems… ugly, yet this seems to be a consequence of the library I'm using.
Best Answer
There is no official place to register all instance variables in Python, nor can there be, since one can add new instance variables dynamically, at any point in the object's lifetime.
Still, it's nice to have a single place to look (and for IDEs to look, as @RemcoGerlich says) to identify what instance variables are typically in play. My solution is to initialize all common instance variables in
__init__
, even if just to a dummyNone
value that will be quickly overwritten. This avoids the uglier multiple value assignment, yet gives humans and IDEs alike a single place to look for an overview of values.This example uses a standard, "public" method name
func
as the initializer. Iffunc
would normally be called from outside the class, this makes sense. Often, however, the function called from__init__
will be private (usually called only by the class, and either just once or infrequently). In that case, you can give further clarity by giving it a more indicative name, and by using an underscore prefix to the method name, which conventionally means "this is a private method." So I might call it_initialize
or_finish_initialization
for example. (Technically speaking, Python doesn't have "private methods," at least not in the enforced-scope way languages like Java do. Private methods are managed by convention/idiom, even if unenforced.)