我有一个包,我想用 sphinx 记录。该包由几个本机模块(使用 boost-python 生成)和一个__init__.py
所述__init__.py确实一堆升压Python模块的(记录的)猴修补的,并提供了一堆便利功能。
我一直无法弄清楚如何告诉 sphinx 基于__init__.py. 我在搜索中发现的只是如何让 sphinx 从类__init__方法生成文档,这不是我所追求的。
我用boost-python包装C++类,我想知道有没有比我现在做的更好的方法.
问题是这些类具有相同名称的getter/setter,并且似乎没有用boost-python包装它的无痛方法.
这是问题的简化版本.鉴于此类:
#include <boost/python.hpp>
using namespace boost::python;
class Foo {
public:
double
x() const
{
return _x;
}
void
x(const double new_x)
{
_x = new_x;
}
private:
double _x;
};
Run Code Online (Sandbox Code Playgroud)
我想做的事情如下:
BOOST_PYTHON_MODULE(foo)
{
class_<Foo>("Foo", init<>())
.add_property("x", &Foo::x, &Foo::x)
;
}
Run Code Online (Sandbox Code Playgroud)
这不起作用,因为boost-python无法确定要使用的函数版本.
事实上,你甚至做不到
.def("x", &Foo::x)
Run Code Online (Sandbox Code Playgroud)
出于同样的原因.
我正在重新阅读boost.org上的教程,有关重载的部分似乎非常有前途.不幸的是,它似乎并不是我想要的.
在重载部分,它提到了一个BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS像这样工作的宏:
如果有另一个成员函数,则Foo使用默认参数:
void z(int i=42)
{
std::cout << i << "\n";
}
Run Code Online (Sandbox Code Playgroud)
然后你可以使用宏:
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(z_member_overloads, z, 0, 1)
Run Code Online (Sandbox Code Playgroud)
然后在BOOST_PYTHON_MODULE:
.def("z", &Foo::z, z_member_overloads())
Run Code Online (Sandbox Code Playgroud)
z_member_overloads …
我最近一直在玩Cython,当我将一个装饰器应用到Cython函数时,我遇到了这个错误
Cdef functions/classes cannot take arbitrary decorators
这是我正在修补的代码:
import functools
def memoize(f):
computed = {}
@functools.wraps(f)
def memoized_f(main_arg, *args, **kwargs):
if computed.get(main_arg):
return computed[main_arg]
computed[main_arg] = f(main_arg, *args, **kwargs)
return computed[main_arg]
return memoized_f
@memoize
cpdef int fib(int n):
return 1 if n < 2 else fib(n - 1) + fib(n - 2)
Run Code Online (Sandbox Code Playgroud)
该错误表明cdef函数只能接受某些装饰器.是否可以编写自己的装饰器,可以应用于cdef函数?
编辑:为未来的读者:
将g = plus_one(_g)在@ DavidW的答复中提到绝招之类的作品.它不适用于递归.例如,fib = memoize(fib)在我的示例代码中,不会记住对fib的递归调用,尽管它会记住顶级调用.即调用fib(5)将memoize 调用的结果fib(5),但它不会记住递归调用(即fib(4), fib(3), fib(2), fib(1)) …
我正在使用cytpes包装 C api。api 函数之一允许您注册回调。我使用CFUNCTYPEto 来指定函数的类型,并CFUNCTYPE从我的 python 库的用户提供的 python 函数中创建一个实例,然后我将其传递给 C 函数(使用ctypesapi调用)。
我知道ctypes调用释放GIL. 我想知道当 C 库函数调用我的 python 回调函数时会发生什么。是否ctypes重新获得GIL?
该文件说:
注意:
CFUNCTYPE()只要在 C 代码中使用对象,请确保保留对对象的引用。ctypes没有,如果你不这样做,它们可能会被垃圾收集,在进行回调时会导致程序崩溃。另外,请注意,如果在 Python 控制之外创建的线程中调用回调函数(例如,通过调用回调的外部代码),则ctypes在每次调用时都会创建一个新的虚拟 Python 线程。这种行为在大多数情况下是正确的,但它意味着存储的值threading.local不会在不同的回调中存活,即使这些调用是从同一个 C 线程进行的。
它没有说任何关于GIL. 是不是说一切都由我来处理?
我有一个问题,我需要将数组的索引传递给我定义内联的函数.然后该函数作为参数传递给另一个函数,该函数最终将其称为回调函数.
问题是,当代码被调用时,索引的值都是错误的.我最终通过创建一个丑陋的解决方法来解决这个问题,但我有兴趣了解这里发生的事情.我创建了一个最小的例子来演示这个问题:
from __future__ import print_function
import threading
def works_as_expected():
for i in range(10):
run_in_thread(lambda: print('the number is: {}'.format(i)))
def not_as_expected():
for i in range(10):
run_later_in_thread(lambda: print('the number is: {}'.format(i)))
def run_in_thread(f):
threading.Thread(target=f).start()
threads_to_run_later = []
def run_later_in_thread(f):
threads_to_run_later.append(threading.Thread(target=f))
print('this works as expected:\n')
works_as_expected()
print('\nthis does not work as expected:\n')
not_as_expected()
for t in threads_to_run_later: t.start()
Run Code Online (Sandbox Code Playgroud)
这是输出:
this works as expected:
the number is: 0
the number is: 1
the number is: 2
the number is: 3
the number is: …Run Code Online (Sandbox Code Playgroud) 是否可以构建具有某些cdef功能的 cython 模块并将生成的共享库链接到 C++ 程序中?
我尝试了一个概念证明:
cymod.pyx:
# distutils: language=c++
from libcpp.string cimport string
cdef public string simple_echo(string test_string):
return test_string
Run Code Online (Sandbox Code Playgroud)
cpp_test.cpp:
#define PyMODINIT_FUNC void
#include <iostream>
#include "cymod.h"
int main(int argc, char const *argv[])
{
std::cout << simple_echo("test") << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
设置.py:
from setuptools import setup, Extension
from Cython.Build import cythonize
setup(
name='cymod',
ext_modules=cythonize(
Extension(
"cymod", ["cymod.pyx"],
),
)
)
Run Code Online (Sandbox Code Playgroud)
cython 模块构建得很好,但是当我尝试构建将使用 cython 函数的 C++ 代码时,我得到:
$ g++ -L. -l:cymod.so cpp_test.cpp -o cpp_test
/tmp/cc48Vc2z.o: In …Run Code Online (Sandbox Code Playgroud) 手册页有这样的内容:
st_info This member specifies the symbol's type and binding
attributes:
STT_NOTYPE The symbol's type is not defined.
STT_OBJECT The symbol is associated with a data object.
STT_FUNC The symbol is associated with a function or other
executable code.
STT_SECTION The symbol is associated with a section. Symbol
table entries of this type exist primarily for
relocation and normally have STB_LOCAL bindings.
STT_FILE By convention, the symbol's name gives the name
of the source file associated with the …Run Code Online (Sandbox Code Playgroud) 鉴于以下枚举:
class MyEnum(IntEnum):
A = 0
B = 1
C = 2
Run Code Online (Sandbox Code Playgroud)
如何指定默认值.我希望能够做到:
my_val = MyEnum()
Run Code Online (Sandbox Code Playgroud)
并具有my_val可<MyEnum.A: 0>
这可能吗?我试过定制__new__,__init__,__call__但我不能得到它的工作.
是否可以子类化int并使其可变?
考虑以下类:
class CustomBitVector(int):
# bit 7
@property
def seventh_property(self):
return bool(self & (1 << 7))
@seventh_property.setter
def seventh_property(self, val):
self |= bool(val) << 7
# bit 6
@property
def sixth_property(self):
return bool(self & (1 << 6))
@sixth_property.setter
def sixth_property(self, val):
self |= bool(val) << 6
# ... a few more of these ...
# bit 0
@property
def zeroth_property(self):
return bool(self & (1 << 0))
@zeroth_property.setter
def zeroth_property(self, val):
self |= bool(val) << 0
Run Code Online (Sandbox Code Playgroud)
我试图为位向量制作一个很好的界面。我正在从套接字读取专有协议,并且我已经创建了类来表示我正在发送/接收的消息。通常这些消息包括位向量,像这样处理它们会很好。
这对于读取位向量值已经很有效,但是设置它们不起作用,因为它int …
python ×7
boost-python ×2
c++ ×2
cython ×2
callback ×1
ctypes ×1
cythonize ×1
elf ×1
enums ×1
gil ×1
immutability ×1
scope ×1
subclass ×1
symbol-table ×1