Bypassing properties on an object (also with __slots__?)

Andrey Fedorov anfedorov at gmail.com
Fri Feb 19 01:30:40 CET 2010


Two questions:

1 - is it documented that o.__dict__[attr] is a reliable way to bypass
property methods?
2 - can one bypass a property method if the class has __slots__?

Reason: I have a couple of different flavors of request objects which I need
to make lazily conform to a standard interface. As a simplified example,

a_foo_request = { 'ip': '1.2.3.4' }
a_bar_request = { 'my-ip': b'\x01\x02\x03\x04' }


My solution is to create two classes:

class FooRequest(dict):
    @property
    def ip(self):
        return self['ip']

class BarRequest(dict):
    @property
    def ip(self):
        return "%i.%i.%i.%i" % struct.unpack("4B", self['my-ip'])


Then:

FooRequest(a_foo_request).ip == '1.2.3.4'

# and
req = BarRequest(a_bar_request)
req.ip == '1.2.3.4'

But some of these getters are CPU-intensive, and since the extended objects
always remain immutable, I memoize them in req.__dict__, like:

class BarRequest(dict):
    @property
    def ip(self):
        if 'ip' in self.__dict__:
            return self.__dict__['ip']
        else:
            self.__dict__['ip'] = "%i.%i.%i.%i" % struct.unpack("4B",
self['my-ip'])
            return self.__dict__['ip']


Which works as intended, and (I think) can be made prettier with a custom
constant_property decorator. So...

Question 0: Is there an obvious better way of achieving this functionality?
Question 1: Is it safe to rely on __dict__ to bypass properties this way?
Question 2: I'd like to use __slots__, but I can't seem to find a way to
stop the property method from recursing. Is there one?

Cheers,
Andrey
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-list/attachments/20100218/db3cea4f/attachment.html>


More information about the Python-list mailing list