我正在努力理解一些围绕 PyCFunction_New 的PyCXX代码(C++ Python 包装器)。
有人可以解释一下这个功能是如何工作的吗?
(我无法从CPython源代码中弄清楚。)
在这里我将详细说明我遇到的问题。我在上面划了一条线,因为这可能不会有如此普遍的用途。
询问的原因是我正在处理奇怪的代码。我有一个关键字方法处理函数:
static PyObject* keyword_handler( PyObject* _self_and_name_tuple,
PyObject* _args,
PyObject* _keywords ) { }
Run Code Online (Sandbox Code Playgroud)
它被存储为:
PyMethodDef meth_def_ext;
meth_def_ext.ml_meth = reinterpret_cast<PyCFunction>( _handler );
meth_def.ml_flags = METH_VARARGS | METH_KEYWORDS;
Run Code Online (Sandbox Code Playgroud)
然后它被捆绑到 PyCFunction_New 中:
MethodDefExt<T>* method_def_ext = ...;
Tuple args{2}; // Tuple wraps a CPython Tuple
args[0] = Object{ this };
args[1] = Object{ PyCapsule_New( (void*)method_def_ext, nullptr, nullptr ), true };
PyObject* func = PyCFunction_New( & method_def_ext->meth_def, args.ptr() );
return Object(func, true);
}
Run Code Online (Sandbox Code Playgroud)
我是否正确地假设 CPython …
我正在尝试使用 Clang 构建 CPython,具有非常具体的要求:
我尝试将 env 变量设置CC为我的 clang 可执行位置(即/opt/llvm/5/bin/clang,但该./configure命令失败并显示以下内容:
configure: error: C compiler cannot create executables
我应该设置哪些标志才能使此构建工作?
我正在尝试使用 C API 构建 Python 字典,但似乎不可能(Py_BuildValue 返回 NULL 对象)使用 PyObject* 作为值。我有这样的情况:
#include <python3.5/Python.h>
...
PyObject *myList = PyList_New(1);
PyList_SetItem(myList, 0, Py_BuildValue("i", 1));
dict = Py_BuildValue("{siso}",
"anInt", myInt,
"aList", mylist);
Run Code Online (Sandbox Code Playgroud)
我正在寻找一种适用于列表通用大小的解决方案。我在官方文档中没有找到任何有关此内容的信息,并且还用谷歌搜索了几个小时。有人可以帮助我吗?提前致谢
尝试使用以下命令从空项目创建轮子setup.py:
from setuptools import setup
setup(name='bla', version='1')
Run Code Online (Sandbox Code Playgroud)
我调用python setup.py bdist_wheel --python-tag py35 --plat-name linux_x86_64并得到
bla-1-py35-none-linux_x86_64.whl
python -V: Python 3.6.9
uname -p: x86_64
Run Code Online (Sandbox Code Playgroud)
正如标题所说,如何制作执行python程序的python3解释器;使用 www.python.org 上提供的普通 CPython 版本可以更快甚至最快;在任何 Linux 发行版中?
有没有办法让它比默认的“--enable-optimizations”编译器标志更快?
使用哪个编译器来实现目标?
有哪些支持性基准来证实编译器选择的断言?
据我所知,cpython 实现为某些相同的值保留相同的对象以节省内存。例如,当我创建 2 个带有 value 的字符串时hello,cpython 不会创建 2 个不同的字符串PyObject:
>>> s1 = 'hello'
>>> s2 = 'hello'
>>> s1 is s2
True
Run Code Online (Sandbox Code Playgroud)
我听说过名字string interning。当我尝试用其他 python 类型检查它时,我发现几乎所有可哈希(不可变)类型都是相同的:
>>> int() is int()
True
>>> str() is str()
True
>>> frozenset() is frozenset()
True
>>> bool() is bool()
True
Run Code Online (Sandbox Code Playgroud)
几乎所有可变类型都是相反的(cpythonPyObject甚至为相同的值创建一个新的类型):
>>> list() is list()
False
>>> set() is set()
False
>>> dict() is dict()
False
Run Code Online (Sandbox Code Playgroud)
我认为这是因为我们可以对PyObject不可变对象使用相同的方法而不会出现任何问题。
当我看到该float类型的行为与其他不可变类型不同时,我的问题就出现了:
>>> float() is float() …Run Code Online (Sandbox Code Playgroud) 如果我有以下C代码:
int main(int argc, char **arg)
{
int x = open("testfilefromc", O_RDWR | O_CREAT);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
当我编译和运行不合理时创建这个:
-rw-r----- 1 joewass staff 0B 31 Jan 21:17 testfilefromc
Run Code Online (Sandbox Code Playgroud)
但是下面的C代码,编译成Python模块:
const char *filename = "testfilefrompython";
context->fd = open(filename, O_RDWR | O_CREAT);
Run Code Online (Sandbox Code Playgroud)
做这个:
---------- 1 joewass staff 165B 31 Jan 21:09 testfilefrompython
Run Code Online (Sandbox Code Playgroud)
毫不奇怪,创建该文件的代码无法在下一轮打开它!
为什么文件会以零权限创建?为什么在编译成Python模块的C中行为会有所不同?我正在运行运行代码的python程序.
为了它的价值,我mmap稍后会把这个文件写进去.
谢谢!
乔
编辑:我知道我可以chmod解决这个问题,问题是为什么?
编辑2:感谢Rosh Oxymoron指出我错过了不那么可选的可选参数.TRWTF是第一个可行的例子!
如果我的理解是正确的,CPython对象将在其引用计数达到零时立即删除.如果您的参考周期变得无法访问逻辑将无法工作,但有时解释器将尝试找到并删除它们(您可以通过调用gc.collect()手动执行此操作).
我的问题是,这些解释器触发的循环收集步骤何时发生?什么样的事件会引发他们?
我对CPython案例更感兴趣,但是很想知道PyPy或其他python实现的不同之处.
Python 3.3添加了__qualname__允许人们获取函数的限定名称(想想module.submodule.class.function)或类似名称的属性.
有没有办法在Python 2.6和2.7中重现这个属性?
以下程序,当链接到python 2.7.13并在Windows 10上运行缓慢但稳定地泄漏内存.
#include <Python.h>
#include <iostream>
int main()
{
std::cout << "Python version: " << PY_VERSION << std::endl;
while (true)
{
Py_Initialize();
//PyGC_Collect();
Py_Finalize();
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
有趣的是,似乎并非每次迭代都会泄漏内存.但我所看到的是,无论泄漏如何,python打印缓慢的引用计数增加了每次迭代大约90次的(非常量)计数.使用Visual Studio诊断工具我发现泄漏来自于PyImport_ImportModule()从磁盘读取已编译模块时的调用(实际调用堆栈深度为几级).
是否还需要我不知道的额外清理步骤?或者有什么关于Python垃圾收集器可能导致这一点,它不是一个"真正的"内存泄漏?
cpython ×10
python ×9
c ×2
c++ ×2
clang ×2
python-c-api ×2
abi ×1
distutils ×1
gcc ×1
immutability ×1
memory-leaks ×1
optimization ×1
pycxx ×1
pyobject ×1
python-2.7 ×1
python-3.x ×1
python-wheel ×1
setuptools ×1