Generic singleton

Terry Reedy tjreedy at udel.edu
Fri Mar 5 16:25:46 EST 2010


On 3/5/2010 1:01 PM, Steven D'Aprano wrote:
> On Fri, 05 Mar 2010 11:57:13 -0500, Terry Reedy wrote:
>
>> On 3/4/2010 10:32 PM, Steven D'Aprano wrote:
>>
>>> Python does have it's own singletons, like None, True and False.
>>
>> True and False are not singletons.
>
> Duotons? Doubletons?

The latter is what I use.
>
>>>> t1 = bool(1)
>>>> t2 = bool(1)
>>>> t1 is t2
> True
>>>> t1 is t2 is bool("this is also true") is bool(['so', 'is', 'this'])
> True
>
> They're described as singletons in the PEP, so if you want to argue with
> Guido, go right ahead... *grin*
> http://www.python.org/dev/peps/pep-0285/

Guido already made the argument ;-) when he followed
'The values False and True will be singletons, like None.'
with 'Because the type has two values, perhaps these should be called 
"doubletons"? '. I agree with him here.

By 'singleton', I believe he meant 'keyword constants' with guaranteed 
'isness'. Ie, "True is True' and 'False is False', like 'None is None', 
are guaranteed in the language def to be true (True) whereas '0 is 0' 
and "'' is ''" and '() is ()' are not, even if they happen to be in a 
particular implementation.

None of this determine the behavior of the respective null and boolean 
classes. If Python had the strict bools that some wanted, bool(x) would 
not be legal.

>>   >  For some reason, they behave quite differently:
>>
>> Because they are quite different.
>
> Well, list("hello world") and list("goodbye now") are quite different
> too, but they behave very similarly.
>
>
>>   >  NoneType fails if you try to instantiate it again,
>>
>> Because trying 'type(None)()' was probably judged to be more likely to
>> be a bug than something useful.

> Obviously people are unlikely to write type(None)(), but they are likely
> to do something like:
>
> result = call_some_function(args)
> more_code_here()
> blah_blah_blah()
> new_obj = type(result)()
> do_something_with(new_obj)
>
> If result happens to end up being None, I'm not convinced that the caller
> would rather have an exception than get the obvious None. If result
> happened to be 0, wouldn't you rather get 0 than have it blow up? I don't
> see why None should be any different.

This is your strongest argument. It has nothing to do in particular with 
(the dubious analogy with) bool. Here is a draft of what you might post 
to python-ideas list, or even the tracker.

"
Make type(None) return None

The built-in classes of CPython nearly all follow the (undocumented?) 
design rule that if class C has a null instance, C() returns that 
(usually unique) null (False) instance. Hence, for instance, one can write

nulls = [type(x)() for x in obs]

to map the objects in obs to their null counterparts. This works for 
object of at least the following classes: bool, int, float, complex, 
str, bytes, bytearray, tuple, list, set, frozenset, dict, 
decimal.Decimal, fractions.Fraction, collections.deque, and 
collections.defaultdict.

The one glaring exception is type(None), which raises a TypeError 
instead of returning the null value None. This anomaly could be easily 
corrected, and the rule documented in, for instance, Lib Ref 5.1. Truth 
Value Testing.

Possible objection 1: None is a special singleton.
Answer 1: False is special too, and 'bool() is False' is true.

Possible objection 2: code that depends on no return would break.
Answer 2: at least one other class was changed during the 2.x series to 
conform to the rule. (xxx which?)
"

I am pretty sure other classes *were* changed, but cannot specifically 
remember which. I would look a bit at the tracker and archives for any 
negative pronouncements between posting.

>>   >  while bool returns the appropriate existing singleton: [sic]
>>
>> Branching on boolean values (which are no more singletons than 0, 1,
>> ...) is basic to computing.
>
> What does that have to do with the price of fish? I didn't mention
> anything about branching on bools.

Every use of 'if', 'and', and 'or' implicitly calls bool, and people 
often call it explicitly. There is almost no use case, other than such 
as the above, for calling the type of None.

> Once a singleton class has been instantiated the first time, you have a
> choice if the user tries to instantiate it again. You can do what
> NoneType does, and raise an error. Or you can do what bool does, and
> return the existing instance.
>
> Obviously, the behaviour of bool is far more useful.

The behavior of bool is necessary.

> So I wonder why NoneType doesn't do the same.

It predated bool by at least a decade.
The choice was pretty inconsequential, especially then, either way.

>>> I wonder why NoneType doesn't just return None?
>>
>> What would you have NoneType(x) do?
>
> The same thing any function of zero arguments does when it gets called
> with one argument.
>
>> Or the special case NoneType(None)?
>
> Why would that be a special case? If NoneType takes no arguments, and you
> supply an argument, then it is an error regardless of what that argument
> happens to be.

I agree. I asked because there were objections to correcting object(x) 
to raise instead of ignore.

Terry Jan Reedy






More information about the Python-list mailing list