8

I'm learning Python and I just finished to learn about the basics of the class. This is the first OOP language I am learning so not everything is very perfectly clear at the moment. Anyway.


I'm wondering if it's possible in Python (3.6), to create a class for which we don't know the attributes of a few objects (or maybe only 2 or 3 among many possible).

For example, let say you want to define a molecule by its properties so that you can use them in another program to model or predict things. The basic properties you can involve will be (for example), Temperature, MolecularWeight and MolarVolume. However, you can also easily define your molecule with 20 different parameters. But, some of them may not exist for every molecule, or you may not need, at the moment, to use them. (i.e. first version of a software, ...).


The question:

I would like to know if a syntax as following exists in Python 3.x, so that the class will be able to create exactly the number of parameters a molecule has. I think it will cost a lot of memory space to define variables which don't exist for thousands of molecules...

class Molecule:

    def __init__(self, Temperature, MolecularWeight, MolarVolume, *properties):
        self.Temperature = Temperature
        self.MolecularWeight = MolecularWeight
        self.MolarVolume = MolarVolume
        self.*properties = *properties

My goal is to use a file .txt to record the properties of my molecules (I have thousands of them) with their properties sorted in a defined order so that when the class is used if for the molecule methanol we have 10 parameters with the first three as mention before, then the class will create the molecule "methanol" with the ten properties in order.


Else, if it doesn't exist, should I by default create a class with all parameters I have in mind and consider some of them as not useful depending on the situations? Or use something much better that exists?

Thank you in advance

ParaH2
  • 519
  • 1
  • 4
  • 21

2 Answers2

8

You can do exactly that by using keyword arguments and the setattr function:

class Molecule:
     def __init__(self, temperature, molecular_weight, molar_volume, **properties):
         self.temperature = temperature
         self.molecular_weight = molecular_weight
         self.molar_volume = molar_volume
         for k, v in properties.items():
             setattr(self, k, v)

I also snake cased your variable names as is convention. Then

m = Molecule(15, 7.5, 3.4, other_property=100)

m.other_property  # returns 100
Alex
  • 18,484
  • 8
  • 60
  • 80
0

Have you heard of dictionaries?

properties = {'A':'value', ... , 'ljkhasdfljkhasdfhj':'value'}

If you add a method called getProperty( propertyName ), you can handle events where the property doesn't exist:

def getProperty ( propName ):
    try:
        return properties[propName]
    except KeyError:
        return "Something went wrong"

The value at a dictionary's key can be any type. For mroe details, the documentation is here: https://docs.python.org/3/tutorial/datastructures.html#dictionaries

Gigaflop
  • 390
  • 1
  • 13
  • 2
    OP specifically asks to use a class. Also `properties.get(propName, "Some indicator of failure")` is more pythonic than this solution. You may also want to check out json [`loads`](https://docs.python.org/3/library/json.html#json.loads) if a dictionary is actually desired. – Alex Jul 31 '18 at 18:48