创新互联Python教程:Python开发模式

python 开发模式

3.7 新版功能.

成都创新互联专注于市中企业网站建设,响应式网站开发,购物商城网站建设。市中网站建设公司,为市中等地区提供建站服务。全流程按需网站开发,专业设计,全程项目跟踪,成都创新互联专业和态度为您提供的服务

开发模式下的 Python 加入了额外的运行时检查,由于开销太大,并非默认启用的。如果代码能够正确执行,默认的调试级别足矣,不应再提高了;仅当觉察到问题时再提升警告触发的级别。

使用 -X dev 命令行参数或将环境变量 PYTHONDEVMODE 置为 1 ,可以启用开发模式。

另请参考 Python debug build 。

Python 开发模式的效果

启用 Python 开发模式后的效果,与以下命令类似,不过还有下面的额外效果:

 
 
 
 
  1. PYTHONMALLOC=debug PYTHONASYNCIODEBUG=1 Python3 -W default -X faulthandler

Python 开发模式的效果:

  • 加入 default warning filter 。下述警告信息将会显示出来:

    • DeprecationWarning

    • ImportWarning

    • PendingDeprecationWarning

    • ResourceWarning

    通常上述警告是由默认的 warning filters 负责处理的。

    效果类似于采用了 -W default 命令行参数。

    使用命令行参数 -W error 或将环境变量 PYTHONWARNINGS 设为 error,可将警告视为错误。

  • 在内存分配程序中安装调试钩子,用以查看:

    • 缓冲区下溢

    • 缓冲区上溢

    • 内存分配 API 冲突

    • 不安全的 GIL 调用

    参见 C 函数 PyMem_SetupDebugHooks() 。

    效果如同将环境变量 PYTHONMALLOC 设为 debug

    若要启用 Python 开发模式,却又不要在内存分配程序中安装调试钩子,请将 环境变量 PYTHONMALLOC 设为 default

  • 在启动 Python 时调用 faulthandler.enable() ,会安装 SIGSEGVSIGFPESIGABRTSIGBUSSIGILL 信号的处理程序,以便在程序崩溃时将 Python 跟踪信息转储下来。

    其行为如同使用了 -X faulthandler 命令行选项或将 PYTHONFAULTHANDLER 环境变量设为 1

  • 启用 asyncio debug mode。比如 asyncio 会检查没有等待的协程并记录下来。

    效果如同将环境变量 PYTHONASYNCIODEBUG 设为 1

  • 检查字符串编码和解码函数的 encodingerrors 参数。例如: open() 、 str.encode() 和 bytes.decode()。

    为了获得最佳性能,默认只会在第一次编码/解码错误时才会检查 errors 参数,有时 encoding 参数为空字符串时还会被忽略。

  • io.IOBase 的析构函数会记录 close() 触发的异常。

  • 将 sys.flags 的 dev_mode 属性设为 True

Python 开发模式下,默认不会启用 tracemalloc 模块,因为其性能和内存开销太大。启用 tracemalloc 模块后,能够提供有关错误来源的一些额外信息。例如,ResourceWarning 记录了资源分配的跟踪信息,而缓冲区溢出错误记录了内存块分配的跟踪信息。

Python 开发模式不会阻止命令行参数 -O 删除 assert 语句,也不会阻止将 __debug__ 设为 False

Python 开发模式只能在 Python 启动时启用。其参数值可从 sys.flags.dev_mode 读取。

在 3.8 版更改: 现在, io.IOBase 的析构函数会记录 close() 触发的异常。

在 3.9 版更改: 现在,字符串编码和解码操作时会检查 encodingerrors 参数。

ResourceWarning 示例

以下示例将统计由命令行指定的文本文件的行数:

 
 
 
 
  1. import sys
  2. def main():
  3. fp = open(sys.argv[1])
  4. nlines = len(fp.readlines())
  5. print(nlines)
  6. # The file is closed implicitly
  7. if __name__ == "__main__":
  8. main()

上述代码没有显式关闭文件。默认情况下,Python 不会触发任何警告。下面用 README.txt 文件测试下,有 269 行:

 
 
 
 
  1. $ python3 script.py README.txt
  2. 269

启用 Python 开发模式后,则会显示一条 ResourceWarning 警告:

 
 
 
 
  1. $ python3 -X dev script.py README.txt
  2. 269
  3. script.py:10: ResourceWarning: unclosed file <_io.TextIOWrapper name='README.rst' mode='r' encoding='UTF-8'>
  4. main()
  5. ResourceWarning: Enable tracemalloc to get the object allocation traceback

启用 tracemalloc 后,则还会显示打开文件的那行代码:

 
 
 
 
  1. $ python3 -X dev -X tracemalloc=5 script.py README.rst
  2. 269
  3. script.py:10: ResourceWarning: unclosed file <_io.TextIOWrapper name='README.rst' mode='r' encoding='UTF-8'>
  4. main()
  5. Object allocated at (most recent call last):
  6. File "script.py", lineno 10
  7. main()
  8. File "script.py", lineno 4
  9. fp = open(sys.argv[1])

修正方案就是显式关闭文件。下面用上下文管理器作为示例:

 
 
 
 
  1. def main():
  2. # Close the file explicitly when exiting the with block
  3. with open(sys.argv[1]) as fp:
  4. nlines = len(fp.readlines())
  5. print(nlines)

未能显式关闭资源,会让资源打开时长远超预期;在退出 Python 时可能会导致严重问题。这在 CPython 中比较糟糕,但在 PyPy 中会更糟。显式关闭资源能让应用程序更加稳定可靠。

文件描述符错误示例

显示自身的第一行代码:

 
 
 
 
  1. import os
  2. def main():
  3. fp = open(__file__)
  4. firstline = fp.readline()
  5. print(firstline.rstrip())
  6. os.close(fp.fileno())
  7. # The file is closed implicitly
  8. main()

默认情况下,Python 不会触发任何警告:

 
 
 
 
  1. $ python3 script.py
  2. import os

在 Python 开发模式下,会在析构文件对象时显示 ResourceWarning 并记录 “Bad file descriptor” 错误。

 
 
 
 
  1. $ python3 script.py
  2. import os
  3. script.py:10: ResourceWarning: unclosed file <_io.TextIOWrapper name='script.py' mode='r' encoding='UTF-8'>
  4. main()
  5. ResourceWarning: Enable tracemalloc to get the object allocation traceback
  6. Exception ignored in: <_io.TextIOWrapper name='script.py' mode='r' encoding='UTF-8'>
  7. Traceback (most recent call last):
  8. File "script.py", line 10, in
  9. main()
  10. OSError: [Errno 9] Bad file descriptor

os.close(fp.fileno()) 会关闭文件描述符。当文件对象析构函数试图再次关闭文件描述符时会失败,并触发 Bad file descriptor 错误。每个文件描述符只允许关闭一次。在最坏的情况下,关闭两次会导致程序崩溃(示例可参见 bpo-18748 )。

修正方案是删除 os.close(fp.fileno()) 这一行,或者打开文件时带上 closefd=False 参数。

当前名称:创新互联Python教程:Python开发模式
文章分享:http://www.csdahua.cn/qtweb/news2/397402.html

网站建设、网络推广公司-快上网,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 快上网