Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Correct way of setting Python class attributes

So I am trying to learn how to properly set Class attributes of a Python class, and wondering about using class functions to do so.

My beginners way has taught me to do:

class MyClass:
    """MyClass class instance"""
    def __init__(self, project, version, command):
        self.project = project
        self.__version = version
        self.__command = command


    """Get version used"""
    def getVersion(self):
        return self.__version

    """Get command executed"""
    def getCommand(self):
        return self.__command

    """Set version used"""
    def setVersion(self, version):
        self.__version = version

This is fine and simple, but this means that I already know the values of my attributes when I instantiate MyClass, since I am passing them to create my object, or if I don't pass them I would use my beginners way of setVersion(version) after creating MyClass object. In my search I read this, which lead me to read about properties, and made me realize that I should not use getter/setters in Python but rather utilize properties. Is this correct?

However, I am wondering if it's Pythonic (or just even correct) to set some of the MyClass instance attributes (project, version, command) using a function. I want to do this because I want this class to do the work of finding these values from specific files by only passing 1 argument. This came to mind, but thought it might be wrong:

class MyClass:
    """MyClass class instance"""
    def __init__(self, project):
        self.project = project
        self._version = self.version()
        self._command = self.command()

    """Get version used"""
    def version(self):
        ...
        use `project` attribute here to get `version` from file...
        ...
        return version

    """Get command executed"""
    def command(self):
        ...
        use `project` attribute here to get `command` from file...
        ...
        return command

Is it even a logical way of setting instance variables by calling a class function?

Should I utilize properties in some ways instead?

Should I make a function outside the MyClass that finds these values returns a MyClass instance instead?

Is there a more proper Pythonic way?

I basically want to create an object with all the extra information (version, command, etc..) by just instantiating it with 1 passed attribute.

Thank you in advance!

like image 407
bretonics Avatar asked Apr 18 '18 18:04

bretonics


People also ask

How do you set a class attribute in Python?

Use dot notation or setattr() function to set the value of a class attribute. Python is a dynamic language. Therefore, you can assign a class variable to a class at runtime. Python stores class variables in the __dict__ attribute.

Which method is used to set attribute in Python?

Python setattr() method is used to assign the object attribute its value.

What is the best way to describe classes in Python?

A class is a code template for creating objects. Objects have member variables and have behaviour associated with them. In python a class is created by the keyword class .


1 Answers

There are many ways to solve this, but this is how I usually do it:

class MyClass:
    """MyClass class instance"""
    def __init__(self, project, version, command):
        self.project = project
        self.version = version
        self.command = command

    @classmethod
    def from_file(cls, project):
        """ 
        Alternate constructor that takes a project 
        and extracts the other attributes from a file
        """
        #... some code to use `project` 
        #... and get `version` and `command` from file
        return cls(project, version, command)

# usage
m = MyClass.from_file('project01')

classmethod is a decorator that makes a method able to be called directly in the class, instead of the instance. The method then will automatically get the class as first parameter. cls is just a name that means class, like we use self for instances but we could use any name really. The main object constructor in __init__ takes full parameters, but the the new from_file class method works as an alternative constructor, by creating an instance of the class and returning it.

Note that this is not a definite answer, but just a suggestion of a pythonic way to solve it.

like image 105
nosklo Avatar answered Nov 14 '22 21:11

nosklo