Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python class __init__ layout?

Tags:

python

class

init

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.

like image 946
Insarov Avatar asked Apr 16 '13 15:04

Insarov


People also ask

What is __ init __? Explain with example?

The __init__ method is the Python equivalent of the C++ constructor in an object-oriented approach. The __init__ function is called every time an object is created from a class. The __init__ method lets the class initialize the object's attributes and serves no other purpose. It is only used within classes.

What is __ init __( self in Python?

The self in keyword in Python is used to all the instances in a class. By using the self keyword, one can easily access all the instances defined within a class, including its methods and attributes. init. __init__ is one of the reserved methods in Python. In object oriented programming, it is known as a constructor.

What is the correct syntax for defining an __ Init__ method in Python?

Python __init__() Function To understand the meaning of classes we have to understand the built-in __init__() function. All classes have a function called __init__(), which is always executed when the class is being initiated.

What is __ init __ In Python class?

"__init__" is a reseved method in python classes. It is called as a constructor in object oriented terminology. This method is called when an object is created from a class and it allows the class to initialize the attributes of the class.


1 Answers

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 propertys:

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.

like image 102
Martijn Pieters Avatar answered Oct 28 '22 08:10

Martijn Pieters