首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么: Python 'Import‘然后再- 'import x as y’clobbers导入x?

为什么: Python 'Import‘然后再- 'import x as y’clobbers导入x?
EN

Stack Overflow用户
提问于 2014-02-04 16:53:19
回答 1查看 439关注 0票数 1

所以,我有一个小小的Python导入的谜团。我相信由于某种原因应该是这样的,因为Guido很少犯错。但是,为什么会这样呢?

代码语言:javascript
复制
$ cat myModule.py
#!/usr/bin/python

class SomeModule(object):

    def __init__(self):
        print "in SomeModule.__init__ ! "

    def doSomething(self):
        print 'doing something.'

$ cat myTest.py
import unittest
from myModule import SomeModule

class TestMyModule(unittest.TestCase):

    def test_001(self):
        print "should see init below"
        sm = SomeModule()
        sm.doSomething()
        print "should see init above\n"

    def test_002(self):
        print "should not see init below."
        from myModule import SomeModule as SM2
        SM2.__init__ = lambda x: None
        sm2 = SM2()
        sm2.doSomething()
        print "should not have seen init above.\n"

    def test_bbb(self):
        print "Should see init below"
        sm = SomeModule()
        sm.doSomething()
        print "should see init above\n"

$ nosetests myTest.py -s
should see init below
in SomeModule.__init__ ! 
doing something.

should see init above
.should not see init below.
doing something.
should not have seen init above.

.Should see init below
doing something.
should see init above
.
----------------------------------------------------------------------
Ran 3 tests in 0.001s

OK

最后的测试应该不受中间测试的影响,对吗?我的直觉说,我不必担心最初的导入,因为第二个导入使用'as‘。因此,在最后一次测试中,我希望看到init,但我没有.

显然,第二个导入,‘从myModule导入SomeModule作为SM2',破坏了某些模块的初始导入,尽管它看起来应该是一个完全独立的实体,如SM2,而不是SomeModule。

这对某人来说有意义吗?

EN

回答 1

Stack Overflow用户

发布于 2014-02-04 17:03:20

这里的“问题”是SM2SomeModule相同的类。在python中,每个模块只有一个“实例”--重新启用将返回对同一个对象的引用:

代码语言:javascript
复制
>>> import code
>>> import code as code2
>>> code is code2
True

在您的代码中,当您运行SM2.__init__ = lambda x: None时,您将替换该类的构造函数。这会影响SM2SomeModule以及可能从myModule导入的任何其他代码。

如果简单地使用SM2= SomeModule对类进行别名化,也会发生同样的事情。

当新程序员开始处理列表并期望分配给一个新变量以复制实际列表时,同样的机制也会让他们感到惊讶:

代码语言:javascript
复制
>>> a=[1]
>>> b=a
>>> b.append(2)
>>> print a
[1, 2]

可以使用is验证代码中对象的标识。注意,这与相等并不相同。

代码语言:javascript
复制
>>> []==[]
True
>>> [] is []
False
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21558543

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档