Why do descriptors (and thus properties) only work on attributes.

Dima Dorfman dima at trit.invalid
Mon Feb 28 16:29:19 EST 2005


On 2005-02-28, Antoon Pardon <apardon at forel.vub.ac.be> wrote:
> Op 2005-02-28, Diez B. Roggisch schreef <deetsNOSPAM at web.de>:
>> I still don't see how that is supposed to work for "a lot of interesting
>> things". Can you provide examples for one of these interesting things?
>
> Lazy evaluation where the value of something is calculated the first
> time it is needed but accessed from some storage if it is needed again.

I do this all the time. It's not very hard and doesn't require any
extra language support, but I would like for there to be an
authoritative list of type slots (autopromise_ops).

    import operator

    def promise(thunk):
        x = []
        def promised():
            if not x:
                x.append(thunk())
            return x[0]
        return promised

    autopromise_ops = [x for x in dir(operator) if x.startswith('__')]
    autopromise_ops += ['__getattribute__', '__call__', '__str__', '__repr__']
    autopromise_ops += ['__getattr__', '__setattr__', '__delattr__']

    def autopromise(thunk):
        p = promise(thunk)
        d = {}
        for op in autopromise_ops:
            def bindhack(op=op):
                return lambda self, *a, **kw: getattr(p(), op)(*a, **kw)
            d[op] = bindhack()
        return type('autopromise', (), d)()

    def test():

        lis = []

        def thunk():
            lis.append('ran thunk')
            return 'value'

        s = autopromise(thunk)
        p = s * 30
        assert p == 'value' * 30
        p = s * 10
        assert p == 'value' * 10
        assert lis == ['ran thunk']          # Just once

        print 'autopromise sanity test passed'

An autopromise object is good almost everywhere the real one would be,
and usually the only way to tell the difference is to call id or type
on it. The main exception is when the thunk returns a builtin type
(like a string or int) and you want to pass it to a builtin function
that expects a particular type (this would also apply to Python
functions that break duck typing on purpose, but those would just be
getting the breakage they deserve).



More information about the Python-list mailing list