is it possible to give an instance a value?

fumanchu fumanchu at amor.org
Tue Mar 6 18:51:59 EST 2007


On Mar 6, 2:45 pm, "manstey" <mans... at csu.edu.au> wrote:
> The question is, is it possible for an instance to have a value (say a
> string, or integer) that can interact with other datatypes and be
> passed as an argument?
>
> The following code of course gives an error:
>
> class Test(object):
>      def __init__(self, val):
>            self.val = val
>
> >>> a = Test('hello')
> >>> a.val  + ' happy'
> 'hello happy'
> >>> a + 'happy'
>
> TypeError: unsupported operand type(s) for +: 'Test' and 'str'
>
> Is there a way to make a have the value a.val when it is used as
> above, or as an argument (eg function(a, 10, 'sdf') etc)?
>
> The only fudge I discovered for simple addition was to add to the
> class
>
>    def __add__(self, obj):
>        return a.val + obj
>
> but this doesn't solve the problem in general. I have tried
> subclassing the string type, but as it is immutable, this is not
> flexible the way a.val is (i.e. it can't e reassigned and remain a
> subclass).
>
> Any pointers, or is my question wrong-headed?
>
> btw, my motivation is wanting to mimic another oo language which
> allows this, so it allows:
>
> >>>Person.Address
> 'Sydney'
> >>>Person.Address.type
> '%String'
> >>>Person.Address = 'Canberra'
> >>>print Person.Address. Person.Address.type
>
> Canberra %String
>
> etc.
>
> We have had to implement Person.Address as Person.Address.val, making
> Address an instance with .val, .type, etc.

The question is not, "is it possible for an instance to have a
value?", but "is it possible for a value to have other attributes?" If
you really need them, you want Python descriptors, which are described
here: http://docs.python.org/ref/descriptors.html. However, if type is
the only value metadata you care about, you probably don't need them
(just use the builtin 'type' function on any object).


class TypedAttribute(object):

    def __init__(self, type=unicode):
        self.type = type

    def __get__(self, obj, unitclass=None):
        if obj is None:
            # When calling on the class instead of an instance...
            return self
        else:
            return obj._attributes[self.key]

    def __set__(self, obj, value):
        obj._attributes[self.key] = value

    def __delete__(self, obj):
        raise AttributeError("TypedAttributes may not be deleted.")


class Person(object):

    Address = TypedAttribute(str)

    def __init__(self):
        self._attributes = {}


I'm using the _attributes dict here just by convention; I find it
convenient to store the underlying values in each parent object. There
are other ways to do it.


Robert Brewer
System Architect
Amor Ministries
fumanchu at amor.org




More information about the Python-list mailing list