Python导入和模块范围(特别是sys.ps1)

Python导入和模块范围(特别是sys.ps1),python,Python,为什么以下方法不起作用: from sys import ps1 ps1 = 'something else ' 但这是真的吗 import sys sys.ps1 = 'something else ' 如果我运行简单的测试 import sys from sys import ps1 ps1 = 'something else' sys.ps1 = 'something else' 第一个作业不起作用,但第二个起作用。ps1和sys.ps1的id()都是相同的,所以它们应该引用相同的东

为什么以下方法不起作用:

from sys import ps1
ps1 = 'something else '
但这是真的吗

import sys
sys.ps1 = 'something else '
如果我运行简单的测试

import sys
from sys import ps1
ps1 = 'something else'
sys.ps1 = 'something else'

第一个作业不起作用,但第二个起作用。ps1和sys.ps1的id()都是相同的,所以它们应该引用相同的东西,对吗?

简短的版本是:赋值在Python中不会改变任何东西,它只是重新绑定名称。重新绑定另一个名称,该名称恰好当前绑定到与
sys.ps1
相同字符串的引用,不会以任何方式影响
sys.ps1

让我们一步一步地进行:

from sys import ps1
这将导入
sys
(但不在当前全局中绑定名称
sys
),然后将当前全局中的名称
ps1
绑定到与
sys
ps1
相同的对象

ps1 = 'something else '
这会将当前全局变量中的名称
ps1
重新绑定到与文本
“其他东西”
相同的对象。没有可能影响
sys
模块的方法

import sys
这将导入
sys
,然后将当前全局文件中的名称
sys
绑定到它

sys.ps1 = 'something else '
这将在当前全局文件中查找名称
sys
,获取对
sys
模块的引用,然后将该模块中的名称
ps1
重新绑定到与文本
“其他东西”
相同的对象


或者,用伪Python术语,而不是英语

您的第一个代码示例如下所示:

tempspace._sys = __import__('sys')
globals.ps1 = tempspace._sys.ps1
del tempspace._sys
globals.ps1 = 'something else '
globals.sys = sys_modules.sys = __import__('sys')
globals.sys.ps1 = 'something else '
你的第二个是这样的:

tempspace._sys = __import__('sys')
globals.ps1 = tempspace._sys.ps1
del tempspace._sys
globals.ps1 = 'something else '
globals.sys = sys_modules.sys = __import__('sys')
globals.sys.ps1 = 'something else '

这是你在评论中描述的内容的副本

Python 2.7.2 (default, Jun 20 2012, 16:23:33) 
[GCC 4.2.1 Compatible Apple Clang 4.0 (tags/Apple/clang-418.0.60)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> from sys import ps1
>>> id(sys.ps1)
4360831168
>>> id(ps1)
4360831168
>>> sys.ps1 = 'something else '
something else ps1
'>>> '
something else 
sys.ps1
ps1
具有相同的ID,因为它们是引用同一对象的两个不同名称


更改
sys.ps1
不会改变
ps1

Python的import语句所造成的混乱程度应该会让它的发明者夜不能寐

ps1 = 'something else '
这里有一个页面,它试图显示。它特别描述了:

  • 导入X导入模块X,使用X.name引用模块X中定义的名称

  • 从X导入*导入模块X,但在 在X中定义的所有公共对象的当前命名空间。您使用name来引用在X中定义的名称,但X本身未定义,因此X.name不起作用

从X import*查看的一种方法可能是,它几乎插入了模块X inline的整个源代码,因此您只需直接使用name,就像它是inline一样,并且您无法使用X,因为它已不存在


请注意,从模块或包导入*的做法是。

如果它将ps1绑定到sys.ps1的副本,它们不会有不同的ID吗?另外,一旦我更改了sys.ps1,ps1也会更改。@维克托:是的,如果你绑定到一个副本,它们有不同的ID,但是如果你绑定到同一个对象,它是同一个对象,所以它当然有相同的ID。当你更改
sys.ps1
时,
ps1
不会更改。让我编辑答案给你看。啊哈。我想我实际上对另一面感到困惑,这也很有趣。如果将
sys.ps1='something other'
替换为
ps1='something other'
,则
ps1
会更改其ID。@victor:是的,因为
ps1
现在具有文本
other'
的ID。这里的关键点是,
ps1
只是一个名称,名称没有ID;是有ID的值。@KevinLondon:不,它不应该起作用。首先,OP没有从X导入*执行
,而是从X导入
执行
。另一方面,这不是他不理解的部分。他已经知道为什么在从sys import ps1
导入
后不能执行
sys.ps1
,但不明白为什么在从sys import ps1
导入
后更改
ps1
不会影响
sys
。你是对的,我的错误。当涉及到Python导入时,我的触发手指很痒;-)