anything like C++ references?

David McNab postmaster at 127.0.0.1
Sun Jul 13 12:58:13 CEST 2003


On Sat, 12 Jul 2003 13:53:35 -0700, Tom Plunket paused, took a deep
breath, then came out with:

> I want to do something along the lines of the following C++ code:
> 
> void change(int& i)
> {
>    i++;
> }

> Is there any way to do references like this in Python?
<snip>

In Python, basic types like strings and numbers are a weird exception to
the 'everything is an object' rule.

When you pass any other object in a function, the function gets a ref to
that object.

But when you pass a string or numeric object, the whole thing (not a ref)
gets passed.

Your best bet would be to create a wrapper class for numbers, store the
actual number in an attribute, and provide all the methods in Section
3.3.6 of the Python Reference Manual (__add__, __sub__ etc) to work on the
value attribute.

That way, you can use your numeric object in calculations, and when you
pass it to functions (like your 'change()' above), things will work as
expected. In fact, in most situations, it will look/feel/smell just like
a number.

But watch out for trying to assign to it, or using '+=' type operators -
they will replace your object with a plain number.

I attach below a sample class declaration for a numeric type which is
passable by reference (no need to do this for string, since you can just
use the UserString module).

Cheers
David

class myint:
    def __init__(self, value):
        self.value = value

    def __getattr__(self, attr):
        if attr in ['__repr__', '__add__', '__repr__', '__add__',
                    '__sub__', '__mul__', '__floordiv__', '__mod__',
                    '__divmod__', '__pow__', '__lshift__',
                    '__rshift__', '__and__', '__xor__', '__or__',
                    '__div__', '__truediv__', '__radd__', '__rsub__',
                    '__rmul__', '__rdiv__', '__rtruediv__',
                    '__rfloordiv__', '__rmod__', '__rdivmod__',
                    '__rpow__', '__rlshift__', '__rrshift__',
                    '__rand__', '__rxor__', '__ror__',
                    '__neg__',
                    '__pos__', '__abs__', '__invert__',
                    '__complex__', '__int__', '__long__',
                    '__float__', '__oct__', '__hex__', '__coerce__']:
            return getattr(self.value, attr)

        def __iadd__(self, other):
            self.value += other
            return self.value

        def __isub__(self, other): self.value -= other
        def __imul__(self, other): self.value *= other
        def __idiv__(self, other): self.value /= other
        def __itruediv__(self, other):
            self.value = self.value.__itruediv__(other)
        def __ifloordiv__(self, other): self.value = self.value.__itruediv__(other)
        def __imod__(self, other): self.value = self.value.__imod__(other)
        def __ipow__(self, other): self.value = self.value.__ipow__(other)
        def __ilshift__(self, other): self.value = self.value.__ilshift__(other)
        def __irshift__(self, other): self.value = self.value.__irshift__(other)
        def __iand__(self, other): self.value = self.value.__iand__(other)
        def __ixor__(self, other): self.value = self.value.__ixor__(other)
        def __ior__(self, other): self.value = self.value.__ior__(other)





More information about the Python-list mailing list