2

I have recently started with Python again, and I am trying to write a module where lots of problems of the following kind occur:

An object Problem can hold a variable Unit. Unit can only be either "inches", "millimeters" or "meters".

The module is supposed to be used by others, so I want the most easily usable solution to this. If possible I want the user to receive an error if they try to assign anything but one of those values.

I see this would be possible with objects where I define a unitClass class that inherits to daughter classes inchesClass, millimetersClass and metersClass. I would then make an instance of each, that the user can assign to the variable in question. But I think this might be confusing, unless that is a standard way to go about such a problem?

The other solution I came up with was set methods but since I don't use them for other variables, I wanted to avoid them in this case as well if possible.

Is there another way to do this using just the modules provided by a standard python installation?

Regards,

RTT

2 Answers2

3

In other languages (namely java), this kind of structure is called an enum or enumeration. Specifically because you enumerate the possible values for something.

In python 3, you can import enum and use it like so:

from enum import Enum

class Color(Enum):

    red = 1
    green = 2
    blue = 3

There's a post that goes more in depth here: How can I represent an 'Enum' in Python?

If you want an example of how to extend this to your specific case I'd do it like so, by creating a Unit enum:

class Unit(Enum):
    inches, millimeters, meters = range(3)

class Problem(object):

    def __init__(self, units):
        self.unit = getattr(Unit(), units) 
Community
  • 1
  • 1
Slater Victoroff
  • 21,376
  • 21
  • 85
  • 144
2

If I understand you correctly, you want to restrict the possible values for a property of an object without usimgna setter function. In Python you can have getters/setters that behave like usual properties. You can do:

class Problem(object):
    @property
    def unit(self):
        return self._unit

    @unit.setter
    def unit(self, val):
        if val in ["inches", "millimeters", "meters"]:
            self._unit = val

I changed Unit because variables that are not types vor singletons usually shouldn't start in upper case.

Cu3PO42
  • 1,403
  • 1
  • 11
  • 19