python - 在 Jupyter Notebook 中使用 Ctypes
问题描述
在 Jupyter Notebook 中,当我尝试打印“hello world!”时 通过 ctypes.cdll.msvcrt.printf 函数它会改变字符串的长度。我只是想学习 ctypes,我想知道为什么会这样?因为如果我尝试在终端中执行该代码,它运行良好。我如何在 Jupyter Notebook 中使用该功能?代码如下。
import ctypes
ctypes.cdll.msvcrt.printf(b"Hello World")
Jupyter Notebook Cell 输出:
11
正常执行输出:
你好世界
解决方案
IPython 不是真正的终端。
IPython(Jupyter Notebook 中的核心)所做的是在数据打印到真实终端之前捕获stdout
,和其他缓冲区。stderr
这发生在 Python 级别。
但是ctypes
,不会使用您的代码在 Python 级别上打印,它使用能够打印数据的函数。该函数存在于系统的共享库中,并且能够在 C 级别上打印(或者更好地说,主要是使用内核中的低级打印函数)。
关于11
值,这可能是您从printf()
函数中获得的结果的长度,如您所说,即len("Hello World")
没有结束\0
字符,但它甚至可能是应该表示通过ctypes.cdll.msvcrt.printf()
. 如果是后者,IPython 会正确捕获输出,但ctypes
只是将其存储在不同的位置(如果有的话)。
我不在 Windows 上,所以不能说结果是什么,但尝试将它存储在一个变量中,然后尝试获取它的属性,您可以从中检索输出并将其插入stdout
for IPython:
out = ctypes.cdll.msvcrt.printf(b"Hello World")
dir(out) # methods, properties, etc
vars(out) # the whole dictionary structure (might fail)
out.__slots__ # __slots__ attribute in case __dict__ for vars() is not present
你可以capture_output()
在这里查看。
推荐阅读
- django-rest-framework - 实现 admin.py 时如何获取外键引用的字段
- oracle - PL/SQL/Oracle DB:过程:ORA-29013:SSL MAC 验证失败(数据库 19c)
- entity-framework-core - 将多个 SQL SELECT 映射到单个无键实体框架核心实体
- spring-boot - 使用 oauth2 保护在 pcf 中运行的 springboot rest api
- java - SpringBoot 连接超时
- arrays - 如何使用 Lua 获取表格中的最小数字
- liquibase - 如何获取 Liquibase 服务器输出
- sql - 如何从 PostgreSQL 中的 bigint 值将日期格式化为“DD-MM-YYYY”
- python - 如果它是python数据框中的字母,则从字符串中删除最后一个字符
- macos - 为什么 c++ SFML 库不适用于 macOS-arm64?