19

I would like to create a class that inherites from None.

Tried this:

class InvalidKeyNone(None):
    pass

but that gives me:

TypeError: Error when calling the metaclass bases
    cannot create 'NoneType' instances

What would be the correct solution that gives me a type that behaves exactly like None but which I can type test?

foo = InvalidKeyNone()
print(type(foo))
>>> InvalidKeyNone

[EDIT]

I want to do this because I am creating a selection scheme on Python datastructures:

bar = select(".foo.bar.[1].x", {"foo":{"bar":[{"x":1}, {"x":2}], "baz":3})
print(bar)
>> 2

And I want to be able to determine whether I get a None because the selected value is None or because the key was not found. HOWEVER it must return a (ducktyped) None that behaves exactly like a None. No exceptions or custom type returning here.

[EDIT]

Ok, so the consensus is: can't be done. Which although unsatisfactory is a valid answer. Since I really want the default behavior to have it return a None when the key is not present I think I will have the select eat a param to switch to exception throwing when appropriate. Thanks.

10
  • 11
    Why would you want to do this?
    – karthikr
    Commented Jul 2, 2013 at 11:35
  • 1
    To expand on the singleton point, even assuming such an object could be constructed, using it would break half of Python's stdlib, because the if x is None: idiom used everywhere tests object identity. Since that pattern is the recommended one, there is no way to construct some None-like type such that instances of it will behave exactly like None.
    – DSM
    Commented Jul 2, 2013 at 11:43
  • 1
    You also don't want to rely on type checking - this is an anti-pattern in Python. You should instead check if an object supports an interface; more of a "try it and see" rather than "check and react". It also looks like what you need is a custom Exception. Commented Jul 2, 2013 at 11:54
  • 1
    "behaves exactly like None" - as far as I'm aware, None has no non-trivial special behavior
    – Eric
    Commented Jul 2, 2013 at 11:55
  • 1
    "HOWEVER it must return a (ducktyped) None that behaves exactly like a None. No exceptions or custom type returning here." Why? Everyone else seems to get by without this unusual need. The standard idiom is to use a custom sentinel, whether a fully specified class type or simply sentinel = object().
    – DSM
    Commented Jul 2, 2013 at 11:56

3 Answers 3

19

None is a constant, the sole value of types.NoneType (for v2.7, for v3.x)

Anyway, when you try to inherit from types.NoneType

from types import NoneType

class InvalidKeyNone(NoneType):
    pass

foo = InvalidKeyNone()
print(type(foo))

you'll get this error

Python 2

TypeError: Error when calling the metaclass bases type 'NoneType' is not an acceptable base type

Python 3

ImportError: cannot import name 'NoneType'

in short, you cannot inherit from NoneType

Anyway, why would want a class to inherit NoneType?

4
  • 1
    In python 3 you could do: type(None) and it returns NoneType
    – skywalker
    Commented Mar 30, 2016 at 15:16
  • I would like to be able to inherit from NoneType, e.g. for dumping to YAML I would then have multiple types that all behave like None but that can be represented in different ways in YAML (NULL, ~, null, the empty scalar, and Null)
    – Anthon
    Commented Jun 1, 2017 at 18:43
  • 4
    class Foo(type(None)): TypeError: type 'NoneType' is not an acceptable base type — :-D Commented Apr 25, 2018 at 6:18
  • 1
    You asked, Anyway, why would want a class to inherit NoneType? It would be nice to inherit from NoneType in order to make null nodes for linked lists and trees. None.left = x raises an exception because None doesn't have an attribute named left. For null nodes of a linked list, you can change that behavior Commented Nov 15, 2019 at 2:39
15

Subclassing None does not make sense, since it is a singleton and There Can Be Only One. You say you want a class with the same behaviour, but None does not have any behaviour!

If what you really want is a unique placeholder that you can return from a function to indicate a special case then simplest way to do this is to create a unique instance of object:

InvalidKey = object()

result = doSomething()
if result is InvalidKey:
    ...
3
  • 3
    Note that the difference here is that bool(None) is False, whereas bool(InvalidKey) is True
    – Eric
    Commented Jul 2, 2013 at 11:57
  • 3
    The solution would be to create a singleton instance of a custom class with __nonzero__ set to return false. Commented Jul 2, 2013 at 12:15
  • 1
    Subclassing None makes a lot of sense when using typing with optional values and sentinels. param: Optional[str] = DefaultNone This allows distinguishing between the default value and explicitly passed None.
    – Ark-kun
    Commented Jun 13, 2023 at 2:01
2

There's no way to do it, at least definitely not until you do some unreadable black magic.

You should probably use exceptions.

1
  • 1
    This. Subclass KeyError and have your code raise that instead of the standard KeyError. Commented Jul 2, 2013 at 11:47

Not the answer you're looking for? Browse other questions tagged or ask your own question.