繁体   English   中英

Python导入-解释

[英]Python Importing - explaination

类似的问题: 了解Python中的导入链

注意:我使用的是Python 3.3,我已经在同一目录中设置了以下两个文件来说明如何导入到我自己,但是我仍然不知道它在做什么。 我了解函数和类定义是需要运行的语句。

untitled.py:

import string

class testing:
    def func(self):
        try:
            print(string.ascii_lowercase)
        except:
            print('not imported')
class second:
    x=1
print('print statement in untitled executed')

stuff.py:

from untitled import testing

try:
    t=testing()
    t.func()
except NameError:
    print('testing not imported')

try:
    print(string.ascii_uppercase)
except NameError:
    print('string not imported')

try:
    print(untitled.string.ascii_uppercase)
except NameError:
    print('string not imported in untitled')

try:
    s=second()
    print(s.x)
except NameError:
    print('second not imported')

这是我从运行stuff.py得到的输出:

print statement in untitled executed
abcdefghijklmnopqrstuvwxyz
string not imported
string not imported in untitled
second not imported

尽管在stuff.py中仅指定了测试类,但仍执行了untitled.py中的print语句。 此外,stuff.py中字符串模块的关系是什么,因为可以从测试类内部调用它,而不能从外部调用它。

有人可以向我解释这种行为吗?“从导入”语句到底做了什么(它运行什么)?

您可以将python模块视为名称空间。 请记住,进口不包括:

  • 模块仅导入一次
  • 第一次执行顶层代码
  • 任何导入,变量,函数或类声明仅影响模块本地名称空间

假设您有一个名为foo.py的模块:

import eggs

bar = "Lets drink, it's a bar'

因此,当您在另一个模块中执行“ from foo import bar时,将使bar在当前名称空间中可用。 如果执行import foo则模块eggs将在foo.eggs下可用。 如果执行from foo import * ,则eggsbar以及模块名称空间中的所有其他内容也将位于当前名称空间中-但从不这样做,Python中不支持通配符导入。

如果你做一个import foo ,然后import eggs ,在顶层代码eggs将被执行一次,模块命名空间将被存储在模块缓存:如果另一个模块导入它的信息将从此缓存中取出。 如果要使用它,则将其导入-无需担心多次导入会多次执行顶层代码。

Python程序员非常喜欢名称空间。 我总是尝试使用import foo ,然后使用foo.bar而不是from foo import bar如果可能的话)-这样可以使命名空间保持整洁并防止名称冲突。

就是说,导入机制是可入侵的,即使不是python的文件,也可以使python import语句正常工作。

关于加载行为, from语句与import没有什么不同。 加载模块时,始终执行顶层代码。 from仅控制将已加载模块的哪些部分添加到当前作用域中(第一点最重要):

from表单使用的过程稍微复杂一些:

  • 查找from子句中指定的模块,并在必要时对其进行初始化;
  • 对于import子句中指定的每个标识符:
    • 检查导入的模块是否具有该名称的属性
    • 如果不是,请尝试导入具有该名称的子模块,然后再次检查导入的模块的该属性
    • 如果找不到该属性,则会引发ImportError。
    • 否则,使用as子句中的名称(如果存在)在本地名称空间中绑定对该值的引用,否则使用属性名称

因此,您可以使用此技巧来访问from部分导入的模块的内容:

print(sys.modules['untitled'].string.ascii_uppercase)

在第一个文件(untitled.py)中,当python编译器解析(因为您在导入时调用了它)时,此文件将创建2个类代码对象并执行print语句。 请注意,如果从命令行运行untitled.py,它甚至会打印出来。

在第二个文件(stuff.py)中,要添加到@Paulo注释中,您仅在namspace中导入了测试类,因此只有untitled.py的2个代码对象中的测试类才可用。但是,如果您只是说

import untitled

您的第三个“ try”语句将起作用,因为它的名称空间中没有标题。

下件事 尝试导入untitled.testing :)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM