IPython 中模块的不一致

huangapple go评论125阅读模式
英文:

Inconsistency on module in IPython

问题

IPython 在这里似乎不一致:

In [1]: import sys

In [2]: sys.version
Out[2]: '3.10.11 (main, May 16 2023, 00:28:57) [GCC 11.2.0]'

In [4]: type(sys)
Out[4]: module

In [5]: type(module)
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[5], line 1
---> 1 type(module)

NameError: name 'module' is not defined

In [6]: type(type(sys))
Out[6]: type

未定义的东西怎么可能是一种类型并具有一种类型呢?

我在发现没有名为 module 的类存在之后发现了这一点,尽管如果我导入我的某个模块,它会自动继承属性:

'__builtins__',
'__cached__',
'__doc__',
'__file__',
'__loader__',
'__name__',
'__package__',
'__spec__',

这些属性是从哪里继承而来的?

英文:

IPython seems inconsistent here:

In [1]: import sys

In [2]: sys.version
Out[2]: '3.10.11 (main, May 16 2023, 00:28:57) [GCC 11.2.0]'

In [4]: type(sys)
Out[4]: module

In [5]: type(module)
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[5], line 1
----> 1 type(module)

NameError: name 'module' is not defined

In [6]: type(type(sys))
Out[6]: type

How can something that is not defined be a type and have a type?

I found this after discovering that no class module exists, although, if I import some module of mine, it automatically inherits attributes

 '__builtins__',
 '__cached__',
 '__doc__',
 '__file__',
 '__loader__',
 '__name__',
 '__package__',
 '__spec__',

What are these attributes inherited from?

答案1

得分: 1

虽然 sys.version 返回 Python 版本号,但我意识到我正在使用 IPython(在Unix命令行中使用 ipython --version 得到版本 8.14.0)。

在 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).
 |

第一个问题的回答

Python 包装了 type 值:

>>> type(2)
<class 'int'>

以便占用更少的空间,但不引用对象:

>>> <class 'int'>
  File "<stdin>", line 1
    <class 'int'>
    ^
SyntaxError: invalid syntax

这一点一开始可能令人困惑,因为在 Python 中一切都应该是对象,但在定义函数时同样会发生:

>>> def f1(x): return x
>>> f1
<function f1 at 0x7f3df38f88b0>

更令人困惑的是,IPython 不显示任何包装。

因此,type(2) 不会评估为 <class 'int'>,而是 int,这与大多数类不同,它们是偶然引用的对象。import(sys); type(sys) 也会评估为 module,这与对象无关。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

包装对象可以通过命名访问:

>>> typeint = type(int)
>>> import sys; typesys = type(sys)
>>> (typeint, typesys)
(<class 'type'>, <class 'module'>)

发生的情况是,int,function,module 在 Python 或 iPython 中都是正常的名称(int = 4 不会引发错误)。

修复 IPython 的一种方法是简单地 import sys; module = type(sys),这样 type(module) 就像 type(int) 一样工作,尽管现在 module 具有这个看似令人困惑的行为:

In [7]: module
Out[7]: module

like

In [1]: int
Out[1]: int

第二个问题的部分回答

类 module 存在。help(type(sys)) 可以使用。

可能有很多子类,可能是 ModuleSpec,尽管我无法证明它。

type 和 class 之间的区别

当 type 被应用两次(或更多次,对任何对象)时,它总是评估为类 type。

>>> type(type(1))
<class 'type'>

在 Python 2.7 中,type(type(1))type(type(sys)) 评估为 <type 'type'>。在 Python ≥ 2.7 中,type 和 class 没有语义上的区别。

替代语法:

>>> int.__class__
<class 'type'>

type 或 class 是它自己的成员:

>>> type(type)
<class 'type'>
>>> type(type) == type
True
>>> type(type) is type
True
>>> isinstance(type, type)
True

class 可以用于定义一个类:

>>> class object: pass

具有功能语法的 type 也可以用于使用三个参数来定义一个类(参见 help(type))。

另请参阅:

英文:

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:

&gt;&gt;&gt; import sys;sys.version
&#39;3.10.11 (main, May 16 2023, 00:28:57) [GCC 11.2.0]&#39;
&gt;&gt;&gt; type(sys)
&lt;class &#39;module&#39;&gt;
&gt;&gt;&gt; type(type(sys))
&lt;class &#39;type&#39;&gt;
&gt;&gt;&gt; typesys=type(sys)
&gt;&gt;&gt; typesys
&lt;class &#39;module&#39;&gt;
&gt;&gt;&gt; type(typesys)
&lt;class &#39;type&#39;&gt;
&gt;&gt;&gt; dir(typesys)
[&#39;__annotations__&#39;, &#39;__class__&#39;, &#39;__delattr__&#39;, &#39;__dict__&#39;, &#39;__dir__&#39;, 
&#39;__doc__&#39;, &#39;__eq__&#39;, &#39;__format__&#39;, &#39;__ge__&#39;, &#39;__getattribute__&#39;, &#39;__gt__&#39;, 
&#39;__hash__&#39;, &#39;__init__&#39;, &#39;__init_subclass__&#39;, &#39;__le__&#39;, &#39;__lt__&#39;, &#39;__ne__&#39;, 
&#39;__new__&#39;, &#39;__reduce__&#39;, &#39;__reduce_ex__&#39;, &#39;__repr__&#39;, &#39;__setattr__&#39;, 
&#39;__sizeof__&#39;, &#39;__str__&#39;, &#39;__subclasshook__&#39;]

&gt;&gt;&gt;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:

&gt;&gt;&gt; type(2)
&lt;class &#39;int&#39;&gt;

so that it takes less space but does not refer to an object:

&gt;&gt;&gt; &lt;class &#39;int&#39;&gt;
  File &quot;&lt;stdin&gt;&quot;, line 1
    &lt;class &#39;int&#39;&gt;
    ^
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:

&gt;&gt;&gt; def f1(x):return x
&gt;&gt;&gt; f1
&lt;function f1 at 0x7f3df38f88b0&gt;

Even more confusing, IPython does not show any wrapper.

Hence, type(2) does not evaluate to &lt;class &#39;int&#39;&gt;) 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
----&gt; 1 function

NameError: name &#39;function&#39; is not defined

The wrapped object can be accessed by naming:

&gt;&gt;&gt; typeint=type(int)
&gt;&gt;&gt; import sys;typesys=type(sys)
&gt;&gt;&gt; (typeint,typesys)
(&lt;class &#39;type&#39;&gt;, &lt;class &#39;module&#39;&gt;)

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.

&gt;&gt;&gt; type(type(1))
&lt;class &#39;type&#39;&gt;

In Python 2.7 type(type(1)) or type(type(sys)) evaluates to &lt;type &#39;type&#39;&gt;. In Python ≥ 2.7, type and class have no semantic difference.

Alternative syntax:

&gt;&gt;&gt; int.__class__
&lt;class &#39;type&#39;&gt;

Type or class is a member of itself:

&gt;&gt;&gt; type(type)
&lt;class &#39;type&#39;&gt;
&gt;&gt;&gt; type(type)==type
True
&gt;&gt;&gt; type(type) is type
True
&gt;&gt;&gt; isinstance(type,type)
True

class can be used to define a class:

&gt;&gt;&gt; class object:pass

type with functional syntax can also be used with 3 parameters to define a class (see help(type)).

See also

huangapple
  • 本文由 发表于 2023年6月19日 07:54:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/76502929.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定