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) _______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor