Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Duplicate None or other Python sigletons

Tags:

python

First of all: This question covers practically zero use cases, and is only about morbid curiosity. That being said:

I started wondering not so long ago if it was possible to duplicate the None object from Python (or any other singleton like True or Ellipsis). By "duplicate", I mean create an exact copy that is not another reference to the same object. That is:

>>> noneBis == None
True
>>> noneBis is None
False

Why I think this would be possible, is because of the core philosophy of Python: Everything is an object. And an object can be copied.

I have tried several ways (some more convoluted than others) and couldn't do it:

>>> copy.deepcopy(None) is None
True
>>> types.NoneType()
TypeError: cannot create NoneType instances
>>> object.__new__(type(None))
TypeError: object.__new__(NoneType) is not safe, use NoneType.__new__()
>>> types.NoneType.__new__(types.NoneType)
TypeError: object.__new__(NoneType) is not safe, use NoneType.__new__()

This seems pretty hardened and mad-scientist-proof to me, but I am not sure I have tried hard enough. (I have tested this in Python 2.7, but since Python 3+ have been designed to be even more foolproof than Python 2, my guess is the results won't be better.)

Can you actually create a separate duplicate of a Python singleton?

like image 490
Nathan.Eilisha Shiraini Avatar asked Dec 12 '25 04:12

Nathan.Eilisha Shiraini


1 Answers

If you could create a "duplicate copy" of a singleton, it wouldn't really be a singleton anymore, would it ?

wrt/ builtin singletons (like None) which are implemented in C (or whatever the language for a given implementation), I don't think you can ever expect to "clone" them except by either fork Python or some similarly extreme method. Also note that since the Python language specs explicitely garantees that None is a singleton, this wouldn't be Python anymore ;)

Now if all you want is something that is a singleton and compares equal to None while not being None, here's a possible (python 2.7.x) implementation:

def __mknone():
    _instance = [None]

    class NotNoneType(object):
        def __new__(cls):
            if _instance[0] is not None:
                raise TypeError("cannot create 'NotNoneType' instances")
            _instance[0] =  object.__new__(cls)
            return _instance[0]

        def __eq__(self, other):
            if other is None:
                return True
            return other == _instance[0]

        def __nonzero__(self):
            return False

    return NotNoneType()

NotNone = __mknone()
NotNoneType = type(NotNone)
del __mknone

Tell me if you manage to create another instance of NotNoneType BTW ;)

like image 180
bruno desthuilliers Avatar answered Dec 16 '25 23:12

bruno desthuilliers



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!