Python class __init__ layout?

class, init, python

Solution

Nope, I don't see why that would be bad form. Calculating those values only once when the instance is created can be a great idea, in fact.

You could also postpone the calculations until needed by using caching `property`s:

class SomeFileType(object):
    _filename = None
    _client = None

    def __init__(self, path):
        self.path = path

    @property
    def filename(self):
        if self._filename is None: 
            filename = os.path.basename(self.path)
            self._filename = os.path.splitext(filename)[0]
        return self._filename

    @property
    def client(self):
        '''Returns client name associated with file'''
        if self._client is None:
            client = self.filename.split()
            self._client = client[1] # Assuming filename is formatted "date client - docTitle"
        return self._client

Now, accessing `somefiletypeinstance.client` will trigger calculation of `self.filename` as needed, as well as cache the result of it's own calculation.

In this specific case, you may want to make `.path` a property as well; one with a setter that clears the cached values:

class SomeFileType(object):
    _filename = None
    _client = None

    def __init__(self, path):
        self._path = path

    @property
    def path(self):
        return self._path

    @path.setter
    def path(self, value):
        # clear all private instance attributes
        for key in [k for k in vars(self) if k[0] == '_']:
            delattr(self, key)
        self._path = value

    @property
    def filename(self):
        if self._filename is None: 
            filename = os.path.basename(self.path)
            self._filename = os.path.splitext(filename)[0]
        return self._filename

    @property
    def client(self):
        '''Returns client name associated with file'''
        if self._client is None:
            client = self.filename.split()
            self._client = client[1] # Assuming filename is formatted "date client - docTitle"
        return self._client

Because `property`-based caching does add some complexity overhead, you need to consider if it is really worth your while; for your specific, simple example, it probably is not. The calculation cost for your attributes is very low indeed, and unless you plan to create large quantities of these classes, the overhead of calculating the properties ahead of time is negligible, compared to the mental cost of having to maintain on-demand caching properties.

Problem

In python, is it bad form to write an `__init__` definition like: ``` class someFileType(object): def __init__(self, path): self.path = path self.filename = self.getFilename() self.client = self.getClient() self.date = self.getDate() self.title = self.getTitle() self.filetype = self.getFiletype() def getFilename(self): '''Returns entire file name without extension''' filename = os.path.basename(self.path) filename = os.path.splitext(filename) filename = filename[0] return filename def getClient(self): '''Returns client name associated with file''' client = self.filename.split() client = client[1] # Assuming filename is formatted "date client - docTitle" return client ``` where the initialized variables are calls to functions returning strings? Or is it considered lazy coding? It's mostly to save me from writing `something.filetype` as `something.getFiletype()` whenever I want to reference some aspect of the file. This code is to sort files into folders by client, then by document type, and other manipulations based on data in the file name.

Original source