Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/neo4j/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在包';s_uuuinit_uuuuu.py_Python - Fatal编程技术网

Python 在包';s_uuuinit_uuuuu.py

Python 在包';s_uuuinit_uuuuu.py,python,Python,main.py: import package package/\uuuuu init\uuuuuuu.py: # use function to split local and global namespace def do_import(): print globals().keys() print locals().keys() import foo as mod print locals().k

main.py:

    import package
package/\uuuuu init\uuuuuuu.py:

    # use function to split local and global namespace
    def do_import():
        print globals().keys()
        print locals().keys()

        import foo as mod

        print locals().keys()
        print globals().keys()

    do_import()
包/foo.py:

    print 'Hello from foo'
Execute main.py的输出如下:

['__builtins__', '__file__', '__package__', '__path__', '__name__', 'do_import', '__doc__']
[]
Hello from foo
['mod']
['__builtins__', '__file__', '__package__', '__path__', '__name__', 'foo', 'do_import', '__doc__']
\uuuu init\uuuuuu.py
中的
导入
未按预期工作。 请注意,全局命名空间有一个“foo”,它应该只绑定到本地“mod”

甚至是
exec在{u_________________________________}中“导入foo作为mod”
无法阻止修改全局命名空间


这怎么会发生呢?

啊!很棘手,但我明白了

“foo”不是一个简单的“其他包”——Python认为它是“包”模块的一个子模块

当您第一次运行“package”——从外部脚本导入它,或者通过使用
-m
命令行开关运行它(但如果您直接从命令行运行
python package/_init__.py
),将解析“package”模块,并将其添加到
sys.modules
脚本中(在
sys
模块上)

读取子模块
foo
时,除了将其直接放置在
sys.modules
[“package.foo”]
下,它还被设置为其父模块的一个属性。因此它在Python应用程序中可以作为
package.foo
使用。发生的事情是在
sys.modules>中设置一个属性[“package”]
,与在运行时在
package/\uuuu init\uuuu.py
globals中设置键具有相同的效果。这就是正在发生的情况

我希望我能把这个过程恰当地用语言表达出来——如果不能,请通过评论再次提问

--
由于这可能发生在您拥有的真实代码中,并且从包外的代码调用“do_import”的等价物(并且有使您的子模块出现在包的全局命名空间上的副作用),因此在您这样做的方式上没有简单的解决方法。我的建议是只添加一个下划线(
\uu
)如果子模块不打算从包外的常规代码调用,则在指定子模块名称时。(在本例中,如果有人从包导入中调用了
*
),则不会显示该名称)

@jsbueno我在python 2.7.3和3.2.3中都尝试过(使用正确的打印语句),这两个版本对我来说都有。我明白发生了什么——我现在正试图用语言来表达。@jsbueno,我的回答错了吗?我不是100%确定,因为这不是我预期的行为,尽管我以前从未真正看过导入之前/之后的globals。@AdamWagner:确实,你的回答不正确。我要说Tmine@jsbueno现在删除我的答案…我不能用一个更简单的测试用例来复制它…我相信我错了。这是有道理的!我认为这与包是一个,嗯,包有关…但是我不能准确地指出到底发生了什么…做得好!我有另一个关于包中init.py的问题。当我想导入如果子模块使用uuu import uu(例如,枚举包目录下的子模块),我必须使用
uu import uu(uuu name uuu+'.foo')
u import('foo',globals())
。这里发生了什么?可能(已经检查过)-Python的导入机制在确定搜索路径前的目录时检查
\uuuuuu file\uuuuuuu
全局变量。可以通过将第二个参数传递给
\uuuuuu import\uuuuuu
来明确这一点is不在默认有效的
\uuuu main\uuu
程序的搜索路径中,但
程序包
是。