views:

32

answers:

2

The main objective of the following module, is to provide a kind of "constant" semantics for some names.

class ConstantError(Exception):

    def __init__(self, msg):
            self._msg = msg


class Constant(object):

    def __init__(self, name):
            self._name = name

    def __get__(self, instance, owner):
            return instance._content[self._name]

    def __set__(self, instance, value):
            raise ConstantError, 'Illegal use of constant'


class Constants(object):

    def __init__(self, content):
            self._content = content
            for k in self._content:
                    setattr(self, k, Constant(k))

num_const = Constants({
    'one': 1,
    'two': 2
})

When used:

>>> from const import *
>>> dir(num_const)
['__class__', '__delattr__', '__dict__', '__doc__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', '__weakref__', '_content', 'one', 'two']

So one and two are there, but the attribute access is diappointing:

>>> num_const.one
<const.Constant object at 0x7faef4871710>
>>>

Where I wold expect 1 in this case. Where am I wrong?

A: 

You are missing a str() or unicode() method in Constants.

Add:

def __unicode__(self):
    return self._name
markmywords
Thanks for your comment. Unfortunately, this does not help to achieve the expected behavior, that is: `num_cons.one` shall look up `'one'` in `num_const._content`, and return its value.
ht
+2  A: 

The descriptor protocol only works on attributes of the class, not on attributes of instances of a class. See the How-To Guide for Descriptors

kaizer.se
So that is the point.Could you please shed some light on the rationale of this behavior? I mean, what else could go wrong if descriptor protocol would work on instances of class also?
ht
I don't know exactly why. Performance concerns for attribute access? Or that it would be hard to access the attribute itself (the descriptor) without invoking it.
kaizer.se