Although sys.version
returns Python version number, I realize that I am using IPython (version 8.14.0 from ipython --version
in the Unix command line.)
The situation differs in Python:
>>> import sys;sys.version
'3.10.11 (main, May 16 2023, 00:28:57) [GCC 11.2.0]'
>>> type(sys)
<class 'module'>
>>> type(type(sys))
<class 'type'>
>>> typesys=type(sys)
>>> typesys
<class 'module'>
>>> type(typesys)
<class 'type'>
>>> dir(typesys)
['__annotations__', '__class__', '__delattr__', '__dict__', '__dir__',
'__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__',
'__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__',
'__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__',
'__sizeof__', '__str__', '__subclasshook__']
>>>help(typesys)
Help on class module in module builtins:
class module(object)
| module(name, doc=None)
|
| Create a module object.
|
| The name must be a string; the optional doc argument can have any type.
|
| Methods defined here:
|
| __delattr__(self, name, /)
| Implement delattr(self, name).
|
Answer to the first question
Python wraps type
value:
>>> type(2)
<class 'int'>
so that it takes less space but does not refer to an object:
>>> <class 'int'>
File "<stdin>", line 1
<class 'int'>
^
SyntaxError: invalid syntax
This is confusing at first since everything is supposed to be an object in Python but the same occurs when defining a function:
>>> def f1(x):return x
>>> f1
<function f1 at 0x7f3df38f88b0>
Even more confusing, IPython does not show any wrapper.
Hence, type(2)
does not evaluate to <class 'int'>
) but int
, which refers to an object by accident with respect to most classes. import(sys);type(sys)
evaluates to module
which does not refer to an object. Same with function
:
In [3]: def f1(x):return x
In [4]: type(f1)
Out[4]: function
In [5]: function
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[5], line 1
----> 1 function
NameError: name 'function' is not defined
The wrapped object can be accessed by naming:
>>> typeint=type(int)
>>> import sys;typesys=type(sys)
>>> (typeint,typesys)
(<class 'type'>, <class 'module'>)
It occurs that int, function, module
are normal names in Python or iPython (int=4
does not throw an error).
One way to fix IPython is simply import sys;module=type(sys)
so that type(module)
works nicely like type(int)
although now module
has this apparently confusing behaviour:
In [7]: module
Out[7]: module
like
In [1]: int
Out[1]: int
Partial answer to the second question
The class module exists. help(type(sys))
works.
Probably, it has many subclasses, possibly ModuleSpec, though I can't prove it.
Difference between type and class
When type is applied twice (or more, on any object) it always evaluates to the class type.
>>> type(type(1))
<class 'type'>
In Python 2.7 type(type(1))
or type(type(sys))
evaluates to <type 'type'>
. In Python ≥ 2.7, type and class have no semantic difference.
Alternative syntax:
>>> int.__class__
<class 'type'>
Type or class is a member of itself:
>>> type(type)
<class 'type'>
>>> type(type)==type
True
>>> type(type) is type
True
>>> isinstance(type,type)
True
class
can be used to define a class:
>>> class object:pass
type
with functional syntax can also be used with 3 parameters to define a class (see help(type)
).
See also