首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何用Python/其他语言管理跨包的模块中的全局数据?

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

Stack Overflow用户
提问于 2009-12-21 16:00:34
回答 3查看 356关注 0票数 1

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

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

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

  1. 假设包可以用Python编译,我说得对吗?
  2. 这两种方法(复制或共享模块数据)有什么优缺点?
  3. 从Python社区的角度来看,Python模块系统是否存在众所周知的问题?例如,是否正在考虑采用PEP来增强模块/包?
  4. Python模块/包系统中是否有某些方面不能很好地适用于编译语言?
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2009-12-21 16:35:11

你问了很多问题。以下是一些进一步发展的提示:

  1. Python代码被词汇和编译成Python特定的指令,但不编译成机器可执行代码。每当您运行与现有的.pyc时间戳不匹配的python代码时,就会自动创建".pyc“文件。此功能可以关闭。您可以使用dis模块来查看这些说明。当一个模块被导入时,它会在它自己的命名空间中执行(从上到下),并全局缓存该名称空间。当您从另一个模块导入时,不会再次执行该模块。记住,def只是一种陈述。您可能需要在代码中放置一个打印(“编译此模块”)语句来跟踪它。
  2. 那得看情况。
  3. 最近有一些增强,主要是关于指定需要加载哪个模块。模块可以有相对路径,因此一个大型项目可能有多个相同名称的模块。
  4. Python本身不适用于编译语言。谷歌为“空载吞下博客”看到了试图加快语言的苦难,在这种语言中,"a = sum(b)“可以改变两次执行之间的含义。在外部的角落案例,模块系统形成了一个良好的桥梁之间的源代码和编译后的库系统。该方法运行良好,Python轻松包装了C代码(swig等)。很有帮助。
票数 3
EN

Stack Overflow用户

发布于 2009-12-21 17:32:07

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

example.py:

代码语言:javascript
运行
复制
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__

互动会议:

代码语言:javascript
运行
复制
>>> 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

你的问题:

  1. 从某种意义上说,它们是编译的,但如果您熟悉C编译器的工作方式,则不会像您预期的那样。
  2. 如果数据是不可变的,复制是可行的,除了对象标识(is操作符和id() )之外,复制应该与共享没有区别。
  3. 导入可能执行代码,也可能不执行代码(它们总是将局部变量分配给对象,但这不会造成问题),并且可能修改或不修改sys.modules。您必须小心不要在线程中导入,通常最好是在每个模块的顶部进行所有导入:这将导致一个级联图,因此所有导入都一次完成,然后__main__继续并执行™工作。
    • 我不知道任何目前的PEP,但已经有很多复杂的机器到位,也。例如,包可以有一个属性 (实际上是一个路径列表),因此子模块不必位于同一个目录中,甚至可以在运行时计算这些路径!(下面的例子是mungepath包。)您可以有自己的导入挂钩,使用函数内部的导入语句,直接调用__import__,我也不会惊讶地发现2-3种处理包和模块的独特方法。

  1. 导入系统的一个子集可以在传统编译的语言中工作,只要它类似于C的#include。您可以在编译器中运行“第一级”执行(创建模块对象),并编译这些结果。然而,这也有明显的缺点,这相当于模块级代码和在运行时执行的函数的单独执行上下文(有些函数必须在这两个上下文中运行!)。(请记住,在Python中,每个语句都是在运行时执行的,甚至是def和class语句。) 。
    • 我认为这是传统编译语言将“顶级”代码限制为类、函数和对象声明的主要原因,从而消除了第二个上下文。即使这样,您也会遇到C/C++中的全局对象(和其他对象)的初始化问题,除非小心管理。

mungepath/__init__..py:

代码语言:javascript
运行
复制
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)

互动会议:

代码语言:javascript
运行
复制
>>> 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
票数 3
EN

Stack Overflow用户

发布于 2009-12-21 16:08:18

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

  1. “包”可以编译成一个包,只是一个模块的集合,它们本身可以被编译。
  2. 考虑到既定的数据范围,我不确定我是否理解。
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1940934

复制
相关文章

相似问题

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