[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

PyWart: More surpises via "implict conversion to boolean" (and other steaming piles!)

On Thu, Feb 13, 2014 at 3:11 PM, Steven D'Aprano <steve at pearwood.info> wrote:
> Think about the difference in difficulty in confirming that
> math.sin() of some value x returns the value 0.5, and confirming that
> random.random() of some hidden state returns a specific value:
> py> assert math.sin(0.5235987755982989) == 0.5
> versus:
> py> state = random.getstate()
> py> random.seed(12345)
> py> assert random.random() == 0.41661987254534116
> py> random.setstate(state)

Really, the assertion just requires the setting of the seed and the
call to random.random(); the other two are to ensure that you don't
fiddle with anything else that's using random.random(). And since
random.random() is actually just a bound method of some module-level
object, you can actually just create the exact same thing with
explicit rather than implicit state:

>>> random.Random(12345).random()

Which doesn't tamper with the default object's state.

Whether it's a module-level function, a bound method, a closure, or a
callable object, a zero-arg function in Python always has some kind of
implicit state. The question is, what is it doing with it? In the case
of random number generation, maintained state is critical (and making
it implicit is usually sufficient); similar with functions like
input(), where the return value doesn't really depend on the argument
at all [1], and of course anything that iterates over an object is
going to need to change some kind of state (either a pointer, or the
actual data, depending on whether you're looking at eg
iter([1,2,3]).next or [1,2,3].pop). Do you know of any functions in
Python that don't use any implicit state and don't take arguments? I
can't think of any, but of course that proves nothing.


[1] input("Enter your name: ") vs input("What is one plus one? ") will
probably return different values, but that's playing with humans
rather than depending on the value of the argument...