12

加载模块时,Python 文档字符串和注释是否存储在内存中?

我想知道这是不是真的,因为我通常会很好地记录我的代码;这会影响内存使用吗?

通常每个 Python 对象都有一个__doc__方法。这些文档字符串是从文件中读取的,还是以其他方式处理的?

我在论坛、谷歌和邮件列表中进行了搜索,但没有找到任何相关信息。

你更了解吗?

4

4 回答 4

25

默认情况下,文档字符串存在于.pyc字节码文件中,并从中加载(注释不存在)。如果您使用python -OO(该-OO标志代表“强烈优化”,而不是-O代表“温和优化),您将获取并使用.pyo文件而不是.pyc文件,并且通过省略文档字符串来优化这些文件(除了由-O, which remove assertstatements). 例如,考虑一个foo.py具有以下内容的文件:

"""This is the documentation for my module foo."""

def bar(x):
  """This is the documentation for my function foo.bar."""
  return x + 1

你可以有以下shell会话......:

$ python -c'import foo; print foo.bar(22); print foo.__doc__'
23
This is the documentation for my module foo.
$ ls -l foo.pyc
-rw-r--r--  1 aleax  eng  327 Dec 30 16:17 foo.pyc
$ python -O -c'import foo; print foo.bar(22); print foo.__doc__'
23
This is the documentation for my module foo.
$ ls -l foo.pyo
-rw-r--r--  1 aleax  eng  327 Dec 30 16:17 foo.pyo
$ python -OO -c'import foo; print foo.bar(22); print foo.__doc__'
23
This is the documentation for my module foo.
$ ls -l foo.pyo
-rw-r--r--  1 aleax  eng  327 Dec 30 16:17 foo.pyo
$ rm foo.pyo
$ python -OO -c'import foo; print foo.bar(22); print foo.__doc__'
23
None
$ ls -l foo.pyo
-rw-r--r--  1 aleax  eng  204 Dec 30 16:17 foo.pyo

请注意,由于我们-O首先使用,该.pyo文件是 327 字节——即使在使用之后-OO,因为该.pyo文件仍然存在并且 Python 没有重建/覆盖它,它只是使用现有的。删除现有的.pyo(或者,等效地,touch foo.py以便 Python 知道.pyo它“已过时”)意味着 Python 会重新构建它(并且,在这种情况下,在磁盘上节省 123 个字节,并且在导入模块时会多一点 - 但是所有.__doc__条目都消失并由None) 代替。

于 2009-12-31T00:21:29.157 回答
12

是的,文档字符串是从文件中读取的,但这不应阻止您编写它们。永远不要为了性能牺牲代码的可读性,直到您完成性能测试并发现您担心的事情实际上是您的程序中导致问题的瓶颈。我认为文档字符串在任何现实世界情况下都不太可能对性能产生任何可衡量的影响。

于 2009-12-31T00:01:59.753 回答
5

它们正在从文件中读取(当文件编译为 pyc 或加载pycobject.__doc__时——它们必须在多兆字节的文档字符串?

于 2009-12-30T23:59:41.443 回答
1

加载模块时,Python 文档字符串和注释是否存储在内存中?

文档字符串被编译到 .pyc 文件中,并被加载到内存中。注释在编译过程中被丢弃,除了在编译过程中忽略它们所花费的微不足道的额外时间(仅在对 .py 文件进行任何更改后发生一次,除了每次重新编译的主脚本之外)跑)。

另请注意,这些字符串仅在它们是模块、类定义或函数定义中的第一件事时才会保留。您几乎可以在任何地方包含附加字符串,但它们将在编译过程中像注释一样被丢弃。

于 2009-12-31T00:23:11.817 回答