Python Mystery Theatre -- Episode 2: Así Fue

Jack Diederich jack at performancedrivers.com
Mon Jul 14 03:50:03 EDT 2003


On Mon, Jul 14, 2003 at 05:42:13AM +0000, Raymond Hettinger wrote:
I didn't look at the code, excepting int() [which is a big exception]
> ACT I -----------------------------------------------
> print '*%*r*' % (10, 'guido')
> print '*%.*f*' % ((42,) * 2)
I'll assume '%r' is __repr__ since '%s' is __str__
The star after a % means "placeholder for a number, get it from the arg list"
so my guess is:
*   'guido'* # padded to ten places, using spaces
*42.000000000000000000000000* # 42 decimal points

> ACT II -----------------------------------------------
> s = '0100'
> print int(s)
> for b in (16, 10, 8, 2, 0, -909, -1000, None):
>     print b, int(s, b)
int(0100) == 64 # octal
I looked up int_new() in intobject.c because I had never used the optional
base parameter.  the 'b' parameter is only legal for 1 >= base <= 36
but the magic constant[1] is -909, which is interpreted as base 10

> ACT III ----------------------------------------------------
> def once(x): return x
> def twice(x): return 2*x
> def thrice(x): return 3*x
> funcs = [once, twice, thrice]
> 
> flim = [lambda x:funcs[0](x), lambda x:funcs[1](x), lambda x:funcs[2](x)]
> flam = [lambda x:f(x) for f in funcs]
> 
> print flim[0](1), flim[1](1), flim[2](1)
> print flam[0](1), flam[1](1), flam[2](1)
funcs, flim, and flam all seem identical to me. all these should print
1 2 3

> ACT IV ----------------------------------------------------
> import os
> os.environ['one'] = 'Now there are'
> os.putenv('two', 'three')
> print os.getenv('one'), os.getenv('two')
no idea, so I'll punt
Now there are three

-jack

[1] When optional arguments are omitted (in this case 'base') the C variable
where they are recorded is left unchanged.  In this case that variable starts
at -909 so if it is passed in as -909 or omitted the code doesn't know.
But why can't base just default to 10 in the first place?  If the result
is -909 (omitted or passed in as -909) we just do a base-10 conversion anyway.

intobject.c

PyObject *x = NULL;
int base = -909;
static char *kwlist[] = {"x", "base", 0};

if (type != &PyInt_Type)
  return int_subtype_new(type, args, kwds); /* Wimp out */
  if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:int", kwlist, &x, &base))
    return NULL;
  if (base == -909)
    return PyNumber_Int(x); /* This will do a base-10 conversion anyway !!! */
  if (PyString_Check(x))
    return PyInt_FromString(PyString_AS_STRING(x), NULL, base);

The only exception is that the first argument has to be a string if the
optional base argument is used.  I'm sure there was a reason for this ... ?
int('99', 10) # legal
int(99, 10) # silly, but should this really be illegal?





More information about the Python-list mailing list