I have a collection of variables in Python, some of which are normal Python numbers and some of which are instances of a class I've written called Property, which represents a range of possible values (e.g. between 0 and 4.2). I want to iterate over this collection and do something different depending on whether each item is a built-in number or a Property. Of course I could do this by explicitly checking the type, but I want to know if there's a clean, object-oriented, idiomatic way to do it in Python.
For example, one of the things I want to do depends on the signs of the collection's entries, so I want to write a function that returns the sign of its argument, regardless of whether it's passed a built-in type or a Property. I can add a __sign__ method to Property, but there's no __sign__ method for built-in numeric types, and Python won't let me add one, so that doesn't help.
Perhaps I'm just making a mistake by having a collection that mixes class instances with built-in types - but changing it would clutter my code's interface. Instead of writing
myList = [0, 2.3, 4, Property(0,2)]
I'd have to write something like
myList = [Property(0), Property(2.3), Property(4), Property(0,2)]
which I'd prefer to avoid if possible.
Here's some more information about what I'm trying to do. I'm working on a scientific problem that involves keeping track of a lot of variables, which interrelate in particular ways. A lot of these variables have known values (because they've been measured) but some are unknown and others have been measured but not accurately, so we know they must lie in some particular range. There are equations that specify the interrelationships between these variables, and ultimately I will use a numerical optimisation library to find the possible ranges of the unknown variables.
Because there are a lot of variables I want to store all the known data about them in a sensibly formatted input file. Although I want to keep this a python file for simplicity, it's important to keep its syntax as simple as possible, both for my sake and because it might have to be read or added to by non-programmers. Currently it has lots of lines that look something vaguely like this:
a.set_some_parameters(3.2, -1, Property(2.3,2.5))
a.x = 0.1
b.x = Property.unknown()
a.set_some_other_parameters(Property.positive(), -4.2, 1, 0)
The point being that (pretty much) anywhere you can enter a number, you can instead enter a Property if the value isn't precisely known. This works well as an interface, but I end up in the situation described above, where my code continually has to deal with the fact that something might be a built-in number, or it might be a Property instance.