模块是Python中唯一真正的全局对象,所有其他全局数据都基于模块系统(使用sys.modules作为注册表)。包只是具有特殊语义的模块,用于导入子模块。”将.py文件编译为.pyc或.pyo并不像大多数语言所理解的那样编译:它只检查语法并创建一个代码对象,在解释器中执行时,它会创建模块对象。
PYP:
print "Creating %s module." % __name__
def show_def(f):
print "Creating function %s.%s." % (__name__, f.__name__)
return f
@show_def
def a():
print "called: %s.a" % __name__
交互式会话:
>>> import example
# first sys.modules['example'] is checked
# since it doesn't exist, example.py is found and "compiled" to example.pyc
# (since example.pyc doesn't exist, same would happen if it was outdated, etc.)
Creating example module. # module code is executed
Creating function example.a. # def statement executed
>>> example.a()
called: example.a
>>> import example
# sys.modules['example'] found, local variable example assigned to that object
# no 'Creating ..' output
>>> d = {"__name__": "fake"}
>>> exec open("example.py") in d
# the first import in this session is very similar to this
# in that it creates a module object (which has a __dict__), initializes a few
# variables in it (__builtins__, __name__, and others---packages' __init__
# modules have their own as well---look at some_module.__dict__.keys() or
# dir(some_module))
# and executes the code from example.py in this dict (or the code object stored
# in example.pyc, etc.)
Creating fake module. # module code is executed
Creating function fake.a. # def statement executed
>>> d.keys()
['__builtins__', '__name__', 'a', 'show_def']
>>> d['a']()
called: fake.a
你的问题:
-
从某种意义上说,它们是编译的,但如果您熟悉C编译器的工作方式,则不会像您所期望的那样进行编译。
-
如果数据是不可变的,那么复制是可行的,除了对象标识之外,复制应该与共享不可区分。(
is
运算符和
id()
在蟒蛇中)。
-
导入可以执行代码,也可以不执行代码(它们总是将局部变量赋给对象,但不会造成任何问题),也可以修改sys.modules,也可以不修改sys.modules。您必须小心不要在线程中导入,通常最好在每个模块的顶部执行所有导入:这会导致一个级联图,因此所有导入都是一次完成的,然后uuMain_uuuuuuuu继续并执行真正的Work™。
-
我不知道现在有什么政治公众人物,但已经有很多复杂的机械设备就位了。例如,包可以具有
__path__ attribute
(实际上是一个路径列表)这样子模块就不必在同一个目录中,甚至可以在运行时计算这些路径!(例如下面的mungepath包。)您可以有自己的导入挂钩,在函数中使用import语句,直接调用uu import_uuuuuuu,我不会惊讶地发现2-3种其他独特的方法来处理包和模块。
-
导入系统的一个子集可以使用传统的编译语言,只要它类似于C's include。您可以在编译器中运行“第一级”执行(创建模块对象),并编译这些结果。但是,这也有很大的缺点,相当于为模块级代码和在运行时执行的函数分离执行上下文(有些函数必须在这两个上下文中运行!)(请记住,在python中,每个语句都是在运行时执行的,甚至是def和class语句。)
-
我认为这是传统编译语言将“顶级”代码限制为类、函数和对象声明的主要原因,从而消除了第二个上下文。即使如此,在C/C++(和其他)中,全局对象也有初始化问题,除非仔细管理。
mungepath/uu init_uuu.py:
print __path__
__path__.append(".") # CWD, would be different in non-example code
print __path__
from . import example # this is example.py from above, and is NOT in mungepath/
# note that this is a degenerate case, in that we now have two names for the
# 'same' module: example and mungepath.example, but they're really different
# modules with different functions (use 'is' or 'id()' to verify)
交互式会话:
>>> import example
Creating example module.
Creating function example.a.
>>> example.__dict__.keys()
['a', '__builtins__', '__file__', 'show_def', '__package__',
'__name__', '__doc__']
>>> import mungepath
['mungepath']
['mungepath', '.']
Creating mungepath.example module.
Creating function mungepath.example.a.
>>> mungepath.example.a()
called: mungepath.example.a
>>> example is mungepath.example
False
>>> example.a is mungepath.example.a
False