[Tutor] recursive problem

Lie Ryan lie.1296 at gmail.com
Sat Sep 11 20:47:00 CEST 2010


On 09/12/10 03:18, Steven D'Aprano wrote:
> Or you could do this:
> 
> if do_this_will_succeed() and do_that_will_succeed() \
> and do_something_else_will_succeed():
>     do_this()
>     do_that()
>     do_something_else()
> else:
>     do_error()
> 
> But that hasn't done anything to prevent race conditions. So the real 
> reason people use LBYL is that they're too lazy to write hideously 
> ugly, but reliable, code, and they're just hoping that they will never 
> expose the race condition. (Often this is a pretty safe hope, but not 
> always.)

Or, probably the best alternative is to mix LBYL and EAFP, e.g.:

attempt = 0
while attempt < 10:
    # first acquire the lock using EAFP
    try:
        lock = acquire_lock()
    except FailToAcquireLock:
        attempt += 1
        time.sleep(1)
    else:
        # Now apply LBYL, since there is no point in doing
        # operations that may be expensive if they will definitely
        # fail by the quick check
        if account_active(fromAcc) and account_active(toAcc)
                and can_withdraw(fromAcc, amount):

            # this operations only writes to a scratch space
            withdraw(fromAcc, amount)
            deposit(toAcc, amount)

            # back to EAFP, since there is no way of assuring
            # this with LBYL
            try:
                # mark the scratch space as permanent change
                commit()
            except CommitFailure:
                raise SeriousError("this can't be happening")
        else:
    finally:
        # LBYL:
        # there is no point in releasing unacquired lock;
        # should probably be done inside release_lock() so that
        # calling release_lock() an unacquired lock safely does nothing
        if not lock:
            release_lock(lock)
else:
    raise Failure("failed to acquire lock")




else:
    do_error("no privilege")

release_lock(lock)



More information about the Tutor mailing list