Is it possible to proxy a Python str and make join work?

I'm trying to implement a lazy-evaluated str-like class. What I have now is simething like

class LazyString(object):

    __class__ = str

    def __init__(self, func):
        self._func = func

    def __str__(self):
        return self._func()

which works fine (for my purposes) in most cases, except one: str.join:

' '.join(['this', LazyString(lambda: 'works')])

fails with

TypeError: sequence item 1: expected string, LazyString found

And after some poking around there doesn't seem to be any magic functions available behind this. join seems to be hard-coded inside the core implementation, and only instances of limited built-in type can make it work without actually being a str.

So am I really out of options here, or is there another way that I'm not aware of?

Answers


join takes strings, so give it strings:

' '.join(map(str, ['this', LazyString(lambda: 'works')]))

Python does not have support for the kind of transparent lazy evaluation you're looking for. If you want to force evaluation of a lazy object, you will have to do so explicitly, rather than having it done automatically when needed. Sometimes, Python will call some method of your object that you can rely on, such as __nonzero__ if you want a lazy boolean, but not always, and you won't generally be able to achieve full interoperability.


Need Your Help

How to get a random number in specific range using Javascript?

javascript

I'm trying to find a way to run in my Node script command that gets a random number from 0.01 to 10.85 for example. The number must look like 0.01 and not like 0.000000001.

Nested Async Functions - Future return running inside Fibers

asynchronous meteor node-fibers

I need to run two nested async functions and return callback from the second one to the client. future.return doesn't work inside Fibers. How to return result to the client without using collection...