Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #20202 > unrolled thread

Postpone evaluation of argument

Started byRighard van Roy <pluijzer@gmail.com>
First post2012-02-11 00:01 +0100
Last post2012-02-11 10:54 +0200
Articles 4 — 4 participants

Back to article view | Back to comp.lang.python


Contents

  Postpone evaluation of argument Righard van Roy <pluijzer@gmail.com> - 2012-02-11 00:01 +0100
    Re: Postpone evaluation of argument Paul Rubin <no.email@nospam.invalid> - 2012-02-10 15:57 -0800
      Re: Postpone evaluation of argument 88888 Dihedral <dihedral88888@googlemail.com> - 2012-02-11 03:16 -0800
    Re: Postpone evaluation of argument Jussi Piitulainen <jpiitula@ling.helsinki.fi> - 2012-02-11 10:54 +0200

#20202 — Postpone evaluation of argument

FromRighard van Roy <pluijzer@gmail.com>
Date2012-02-11 00:01 +0100
SubjectPostpone evaluation of argument
Message-ID<mailman.5686.1328914914.27778.python-list@python.org>
Hello,

I want to add an item to a list, except if the evaluation of that item
results in an exception.
I could do that like this:

def r(x):
    if x > 3:
        raise(ValueError)

try:
    list.append(r(1))
except:
    pass
try:
    list.append(r(5))
except:
    pass

This looks rather clumbsy though, and it does not work with i.e. list
comprehensions.

I was thinking of writing a decorator like this:

def tryAppendDecorator(fn):
    def new(*args):
        try:
            fn(*args)
        except:
            pass
    return new

@tryAppendDecorator
def tryAppend(list, item):
    list.append(item)

tryAppend(list, r(1))
tryAppend(list, r(5))

This does not work however because the 'item' argument gets evaluated
before the decorator does it's magic.

Is there a way to postpone the evaluation of 'item' till it gets used
inside the decorator. Like it is possible to quote a form in Lisp.

Thank you,
Righard

[toc] | [next] | [standalone]


#20206

FromPaul Rubin <no.email@nospam.invalid>
Date2012-02-10 15:57 -0800
Message-ID<7xsjii2qd7.fsf@ruckus.brouhaha.com>
In reply to#20202
Righard van Roy <pluijzer@gmail.com> writes:
> I want to add an item to a list, except if the evaluation of that item
> results in an exception.

This may be overkill and probably slow, but perhaps most in the spirit
that you're asking.

    from itertools import chain

    def r(x):
        if x > 3:
            raise(ValueError)
        return x

    def maybe(func):
      try:
         yield func()
      except:
         return

    def p(i): return maybe(lambda: r(i))

    your_list = list(chain(p(1), p(5)))
    print your_list

[toc] | [prev] | [next] | [standalone]


#20220

From88888 Dihedral <dihedral88888@googlemail.com>
Date2012-02-11 03:16 -0800
Message-ID<412049.429.1328958999552.JavaMail.geo-discussion-forums@pbctz8>
In reply to#20206
在 2012年2月11日星期六UTC+8上午7时57分56秒,Paul Rubin写道:
> Righard van Roy 
>  writes:
> > I want to add an item to a list, except if the evaluation of that item
> > results in an exception.
> 
> This may be overkill and probably slow, but perhaps most in the spirit
> that you're asking.
> 
>     from itertools import chain
> 
>     def r(x):
>         if x > 3:
>             raise(ValueError)
>         return x
> 
>     def maybe(func):
>       try:
>          yield func()
>       except:
>          return
> 
I am wondering at which level to yield in a nested decorated function
is more controllable. 

It is definitely wrong to yield in manny levels decorated.


>     def p(i): return maybe(lambda: r(i))
> 
>     your_list = list(chain(p(1), p(5)))
>     print your_list

[toc] | [prev] | [next] | [standalone]


#20217

FromJussi Piitulainen <jpiitula@ling.helsinki.fi>
Date2012-02-11 10:54 +0200
Message-ID<qotk43tyclp.fsf@ruuvi.it.helsinki.fi>
In reply to#20202
Righard van Roy writes:

> Hello,
> 
> I want to add an item to a list, except if the evaluation of that item
> results in an exception.
> I could do that like this:
> 
> def r(x):
>     if x > 3:
>         raise(ValueError)
> 
> try:
>     list.append(r(1))
> except:
>     pass
> try:
>     list.append(r(5))
> except:
>     pass
> 
> This looks rather clumbsy though, and it does not work with i.e. list
> comprehensions.
> 
> I was thinking of writing a decorator like this:
> 
> def tryAppendDecorator(fn):
>     def new(*args):
>         try:
>             fn(*args)
>         except:
>             pass
>     return new
> 
> @tryAppendDecorator
> def tryAppend(list, item):
>     list.append(item)
> 
> tryAppend(list, r(1))
> tryAppend(list, r(5))
> 
> This does not work however because the 'item' argument gets evaluated
> before the decorator does it's magic.
> 
> Is there a way to postpone the evaluation of 'item' till it gets used
> inside the decorator. Like it is possible to quote a form in Lisp.

That's not considered good practice in Lisp either. One would use a
lambda expression to delay the computation, as others have suggested.

You might be able to arrange your program so that tryAppend is called
with the error-raising function and its arguments separately. I mean
like this:

def r(x):
    if x > 3:
        raise(ValueError)
    return x

def tryAppendDecorator(fn):
    def new(xs, f, *args):
        try:
            fn(xs, f(*args))
        except:
            pass
    return new

@tryAppendDecorator
def tryAppend(items, item):
    items.append(item)

sub3 = []
tryAppend(sub3, r, 3)
tryAppend(sub3, r, 1)
tryAppend(sub3, r, 4)
tryAppend(sub3, r, 1)
tryAppend(sub3, r, 5)

Maybe you should only ignore some specific type of exception, like
ValueError if you are specifically using r as a filter whose task it
is to raise a ValueError.

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web