Question about 'None'

Francis Girard francis.girard at free.fr
Thu Jan 27 22:19:41 CET 2005


Le jeudi 27 Janvier 2005 22:07, Steven Bethard a écrit :
> Francis Girard wrote:
> > Le jeudi 27 Janvier 2005 21:29, Steven Bethard a écrit :
> >>So None being smaller than anything (except itself) is hard-coded into
> >>Python's compare routine.  My suspicion is that even if/when objects of
> >>different types are no longer comparable by default (as has been
> >>suggested for Python 3.0), None will still compare as smaller than
> >>anything...
> >
> > Well, here's python doesn't seem to confirm what you're saying :
> >>>>a = "10"
> >>>>b = 10
> >>>>a > b
> >
> > True
> >
> >>>>b > a
> >
> > False
> >
> >>>>id(a)
> >
> > 1077467584
> >
> >>>>id(b)
> >
> > 134536516
>
> Actually, this code doesn't contradict what I said at all.  I said that
> None (and only None) was special-cased.
>

You're right. I just posted too soon.
Sorry.

> > It really looks like the addresses are compared when objects are of
> > different types if there is no __cmp__ or __lt__ user made specification
> > to compare objects of different types.
>
> Use the source Luke! ;)  Download it from CVS and take a look.  The end
> of default_3way_compare:
>

Just want to know the specifications. No matter how it had been implemented.

> static int
> default_3way_compare(PyObject *v, PyObject *w)
> {
> 	...
> 	/* None is smaller than anything */
> 	if (v == Py_None)
> 		return -1;
> 	if (w == Py_None)
> 		return 1;
>
> 	/* different type: compare type names; numbers are smaller */
> 	if (PyNumber_Check(v))
> 		vname = "";
> 	else
> 		vname = v->ob_type->tp_name;
> 	if (PyNumber_Check(w))
> 		wname = "";
> 	else
> 		wname = w->ob_type->tp_name;
> 	c = strcmp(vname, wname);
> 	if (c < 0)
> 		return -1;
> 	if (c > 0)
> 		return 1;
> 	/* Same type name, or (more likely) incomparable numeric types */
> 	return ((Py_uintptr_t)(v->ob_type) < (
> 		Py_uintptr_t)(w->ob_type)) ? -1 : 1;
> }
>
> So it looks like Python uses the type name.  Testing this:
>
> py> A = type('A', (object,), {})
> py> Z = type('Z', (object,), {})
> py> lst = [str('a'), dict(b=2), tuple(), Z(), A()]
> py> [type(o).__name__ for o in lst]
> ['str', 'dict', 'tuple', 'Z', 'A']
> py> sorted(type(o).__name__ for o in lst)
> ['A', 'Z', 'dict', 'str', 'tuple']
> py> sorted(lst)
> [<__main__.A object at 0x011E29D0>, <__main__.Z object at 0x011E29F0>,
> {'b': 2}, 'a', ()]
>
> Yup.  Looks about right.  (Note that the source code also special-cases
> numbers...)
>
> So, the order is consistent, but arbitrary, just as Fredrik Lundh
> pointed out in the documentation.
>

Ok. Thank you,

Francis Girard


> Steve




More information about the Python-list mailing list