如何/应该用Python/其他语言管理跨包模块中的全局数据?

2024-05-20 15:00:52 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试为编程语言(Heron)设计包和模块系统,它既可以编译也可以解释,从我所看到的来看,我非常喜欢Python方法。Python有丰富的模块选择,这似乎在很大程度上促成了它的成功。

我不知道的是,如果一个模块包含在两个不同的编译包中,Python会发生什么:数据是单独的副本还是共享的?

与此相关的是一系列附带问题:

  1. 我假设包可以用Python编译对吗?在
  2. 这两种方法(复制或共享模块数据)有哪些优缺点?在
  3. 从Python社区的角度来看,Python模块系统是否存在广为人知的问题?例如,是否有一个政治公众人物正在考虑增强模块/软件包?在
  4. Python模块/包系统是否有某些方面不适合编译语言?在

Tags: 模块数据方法系统副本附带编程语言社区
3条回答

模块是Python中唯一真正的全局对象,所有其他全局数据都基于模块系统(它使用系统模块作为注册表)。包只是具有特殊语义的模块,用于导入子模块。”将.py文件编译成.pyc或.pyo并不像大多数语言所理解的那样进行编译:它只检查语法并创建一个code对象,当在解释器中执行时,它将创建module对象。在

在示例.py公司名称:

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__

互动环节:

^{pr2}$

您的问题:

  1. 从某种意义上说,它们是经过编译的,但如果您熟悉C编译器的工作原理,则不会像您预期的那样。在
  2. 如果数据是不可变的,那么复制是可行的,并且除了对象标识(Python中的is操作符和id())之外,复制是可行的。在
  3. 导入可以执行也可以不执行代码(它们总是为对象分配一个局部变量,但这不会产生问题),并且可以修改也可以不修改系统模块. 通常情况下,在所有的主模块中,你都必须小心导入,这样你就不能再做真正的导入了™.
    • 我不知道现在有什么政治公众人物,但已经有很多复杂的机制在那里。例如,包可以有一个__path__ attribute(实际上是一个路径列表),这样子模块就不必在同一个目录中,甚至可以在运行时计算这些路径!(例如下面的mungepath包。)您可以拥有自己的导入钩子,在函数内使用import语句,直接调用yu import_uu,我会发现2-3种其他独特的方法来处理包和模块。在
  4. 导入系统的一个子集可以用传统的编译语言工作,只要它类似于C的include。您可以在编译器中运行“第一级”执行(创建模块对象),并编译这些结果。然而,这样做有很大的缺点,相当于将模块级代码和运行时执行的函数分开执行上下文(有些函数必须在这两个上下文中运行!)。(请记住,在Python中,每个语句都是在运行时执行的,甚至def和class语句也是如此。)
    • 我相信这就是传统编译语言将“顶级”代码限制为类、函数和对象声明的主要原因,从而消除了第二个上下文。即使如此,您也可以在C/C++(和其他)中对全局对象进行初始化问题,除非仔细管理。在

mungepath/\uu init_uu.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

你问了很多问题。下面是一些提示,可以进一步了解:

  1. a.Python代码是经过词法分析和编译成Python特定指令的,但不是编译成机器可执行代码。每当运行与现有的.pyc时间戳不匹配的python代码时,.pyc”文件将自动创建。此功能可以关闭。您可以使用dis模块来查看这些说明。 b、 当一个模块被导入时,它将在它自己的命名空间中执行(从上到下),并且该命名空间被全局缓存。从其他模块导入时,不会再次执行该模块。记住def只是一个声明。您可能需要在代码中放入print('compileding this module')语句来跟踪它。

  2. 要看情况而定。

  3. 最近有一些改进,主要是关于指定需要加载哪个模块。模块可以有相对路径,这样一个巨大的项目可能有多个同名的模块。

  4. Python本身不适合编译语言。谷歌搜索“unladen swallow blog”以了解试图加速一种“a=sum(b)”可以在两次执行之间改变含义的语言所带来的痛苦。在角落案例之外,模块系统在源代码和编译的库系统之间形成了一个很好的桥梁。这种方法效果很好,Python对C代码的简单包装(swig等)也有帮助。

全局数据的作用域在解释器级别。在

  1. “包”可以编译为一个包,它只是一个模块的集合,这些模块本身可以被编译。在
  2. 鉴于数据范围的确定,我不确定我是否理解。在

相关问题 更多 >