简体   繁体   中英

Python module __builtin__ has no attribute NoneType

For reasons out of scope of this question, I'm building a serialization mechanism. I've run into a problem with None objects that I think I need to special case. Can anybody explain why NoneType is treated differently from other builtin types? Or am I missing something?

>>> import sys
>>> builtin = sys.modules['__builtin__']
>>> getattr(builtin,'int')
<type 'int'>
>>> getattr(builtin,'list')
<type 'list'>
>>> getattr(builtin,'NoneType')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'NoneType'

python 2.6.5 on Ubuntu

Clarification

Of course

getattr(builtin,'None')

works and returns a None object, which is an instance of NoneType . But the class object exists in the __builtin__ module for everything else. So this code works for every built in type except None :

klass = getattr(builtin, obj.__class__.__name__)

which makes sense given that

>>> type(0).__module__
'__builtin__'
>>> type("foo").__module__
'__builtin__'
>>> type(None).__module__
'__builtin__'

The fact that this fails for None seems like an oversight in Python, unless I'm missing something.

I suppose what you call NoneType is treated specially because you hardly never need to access it. You could say

>>> NoneType = type(None)

to bind this type to a name, but that would serve no common purpose: isinstance(x, NoneType) would be a contrived equivalent to x is None ; the constructor raises a TypeError stating that you're not supposed to construct instances; and deriving from it is forbidden too.

You can still get to the type via either type(None) , None.__class__ , or types.NoneType , though, if you need it for some advanced purpose.

NoneType is available in the types module.

>>> import types
>>> types.NoneType
<type 'NoneType'>

Infact types module is the right place to use if you are doing anything with types, don't rely on types being present in the builtins

It is probably to do something with the fact that None is not really a type, it sa builtin constant . Even the docs say the type of None is types.NoneType, but you are right it is implemented in a special manner and is inconsistent from all other types.

It is odd. But so are plenty of odd things about classes and objects in python 2. This is true of a bunch of languages that evolved from simple scripts to full-fledged OO. Python 3 is intended to solve this.

NoneType is a special case already because it is the class object for a singleton, so it can't be called as a constructor.

TypeError: cannot create 'NoneType' instances

So, if you are writing a general serializer then you will need to special case None anyway, irregardless of whether you can't look up the class object.

Have you tried looking at:

>>> dir(builtin)
['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException', 'BufferError', 'BytesWarning', 'DeprecationWarning', 'EOFError', 'Ellipsis', 'EnvironmentError', 'Exception', 'False', 'FloatingPointError', 'FutureWarning', 'GeneratorExit', 'IOError', 'ImportError', 'ImportWarning', 'IndentationError', 'IndexError', 'KeyError', 'KeyboardInterrupt', 'LookupError', 'MemoryError', 'NameError', 'None', 'NotImplemented', 'NotImplementedError', 'OSError', 'OverflowError', 'PendingDeprecationWarning', 'ReferenceError', 'RuntimeError', 'RuntimeWarning', 'StandardError', 'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError', 'SystemExit', 'TabError', 'True', 'TypeError', 'UnboundLocalError', 'UnicodeDecodeError', 'UnicodeEncodeError', 'UnicodeError', 'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning', 'ValueError', 'Warning', 'ZeroDivisionError', '_', '__debug__', '__doc__', '__import__', '__name__', '__package__', 'abs', 'all', 'any', 'apply', 'basestring', 'bin', 'bool', 'buffer', 'bytearray', 'bytes', 'callable', 'chr', 'classmethod', 'cmp', 'coerce', 'compile', 'complex', 'copyright', 'credits', 'delattr', 'dict', 'dir', 'divmod', 'enumerate', 'eval', 'execfile', 'exit', 'file', 'filter', 'float', 'format', 'frozenset', 'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex', 'id', 'input', 'int', 'intern', 'isinstance', 'issubclass', 'iter', 'len', 'license', 'list', 'locals', 'long', 'map', 'max', 'memoryview', 'min', 'next', 'object', 'oct', 'open', 'ord', 'pow', 'print', 'property', 'quit', 'range', 'raw_input', 'reduce', 'reload', 'repr', 'reversed', 'round', 'set', 'setattr', 'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'unichr', 'unicode', 'vars', 'xrange', 'zip']

NoneType is not listed as a builtin type (even though None is)

you should try : getattr(builtin,"None") not getattr(builtin,"NoneType") , as NoneType is the value of type(None) , so it's not an attribute of builtin .

In [49]: type(None)

Out[49]: <type 'NoneType'>

this doesn't works, as Python is not able to find out NoneType anywhere.

In [50]: type(NoneType)
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)

/home/monty/<ipython console> in <module>()
NameError: name 'NoneType' is not defined

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM