This is a container class, suitable for use to answer the question "How do I pass a reference to a variable to a function", abusing some of the methods to get a syntax that's easier to use than more conventional containers.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
class Ref(object): _unbound = object() def __new__(cls, value = _unbound): """We're an object, but need to ignore the optional argument.""" return object.__new__(cls) def __init__(self, value = _unbound): """Bind the optional value, if provided.""" if value is not self._unbound: self._value = value def __pos__(self): """Return value, if bound.""" try: return self._value except AttributeError: raise NameError, "%s object does not have a value stored." % \ self.__class__.__name__ def __iadd__(self, value): self._value = value return self
A common question on comp.lang.python is "How do I pass a reference to a variable to change it in a function." This usually comes from people used to other languages, where that's the solution of choice for returning multiple values. The better solution for this in Python is to return a tuple and assign the new value to the variable. However, answers involving using a container class for the variable always surface, with the usual objection that the syntax for them is ugly.
The Ref class is designed to be a simple container class with a cleaner syntax than other alternatives. It abuses the ability to have operators invoke methods to use the monadic plus and add-assign operator to retrieve and set the values in the container. I.e.:
a = Ref(20) print +a # Prints 20 b = a b += 23 print +a # Prints 23 a += "Testing" print +b # Prints 23
The problem with your solution is that you must wrap all of the underlying methods to be effective. I personally prefer the standard answer of "use a list."
No other wrappers needed. I clearly didn't provide sufficient examples. You use a Ref object just like you'd use a list, except the syntax for setting/reading a value looks more like an extended lambda-calculus Cell than a list. Where you'd write arg in a method if you passed a list, you'd write +arg to get the value, and arg = value becomes arg += value.
To write the classic "inc" function, you'd write: