Cython,使队列代码可以存储任何类型的数据

时间:2018-07-27 14:56:08

标签: python cython

我读了很棒的Tutorial of Using C libraries并修改了代码,以便template <typename T=float> class XVector3 { public: typedef T value_type; __host__ __device__ inline XVector3() : x(0.0f), y(0.0f), z(0.0f) {} __host__ __device__ inline XVector3(T a) : x(a), y(a), z(a) {} __host__ __device__ inline XVector3(const T* p) : x(p[0]), y(p[1]), z(p[2]) {} __host__ __device__ inline XVector3(T x_, T y_, T z_) : x(x_), y(y_), z(z_) { VEC3_VALIDATE(); } __host__ __device__ inline operator T* () { return &x; } __host__ __device__ inline operator const T* () const { return &x; }; __host__ __device__ inline void Set(T x_, T y_, T z_) { VEC3_VALIDATE(); x = x_; y = y_; z = z_;} __host__ __device__ inline XVector3<T> operator * (T scale) const { XVector3<T> r(*this); r *= scale; return r; VEC3_VALIDATE();} __host__ __device__ inline XVector3<T> operator / (T scale) const { XVector3<T> r(*this); r /= scale; return r; VEC3_VALIDATE();} __host__ __device__ inline XVector3<T> operator + (const XVector3<T>& v) const { XVector3<T> r(*this); r += v; return r; VEC3_VALIDATE();} __host__ __device__ inline XVector3<T> operator - (const XVector3<T>& v) const { XVector3<T> r(*this); r -= v; return r; VEC3_VALIDATE();} __host__ __device__ inline XVector3<T> operator /(const XVector3<T>& v) const { XVector3<T> r(*this); r /= v; return r; VEC3_VALIDATE();} __host__ __device__ inline XVector3<T> operator *(const XVector3<T>& v) const { XVector3<T> r(*this); r *= v; return r; VEC3_VALIDATE();} __host__ __device__ inline XVector3<T>& operator *=(T scale) {x *= scale; y *= scale; z*= scale; VEC3_VALIDATE(); return *this;} __host__ __device__ inline XVector3<T>& operator /=(T scale) {T s(1.0f/scale); x *= s; y *= s; z *= s; VEC3_VALIDATE(); return *this;} __host__ __device__ inline XVector3<T>& operator +=(const XVector3<T>& v) {x += v.x; y += v.y; z += v.z; VEC3_VALIDATE(); return *this;} __host__ __device__ inline XVector3<T>& operator -=(const XVector3<T>& v) {x -= v.x; y -= v.y; z -= v.z; VEC3_VALIDATE(); return *this;} __host__ __device__ inline XVector3<T>& operator /=(const XVector3<T>& v) {x /= v.x; y /= v.y; z /= v.z; VEC3_VALIDATE(); return *this; } __host__ __device__ inline XVector3<T>& operator *=(const XVector3<T>& v) {x *= v.x; y *= v.y; z *= v.z; VEC3_VALIDATE(); return *this; } __host__ __device__ inline bool operator != (const XVector3<T>& v) const { return (x != v.x || y != v.y || z != v.z); } // negate __host__ __device__ inline XVector3<T> operator -() const { VEC3_VALIDATE(); return XVector3<T>(-x, -y, -z); } __host__ __device__ void Validate() { VEC3_VALIDATE(); } T x,y,z; }; typedef XVector3<float> Vec3; typedef XVector3<float> Vector3; // lhs scalar scale template <typename T> __host__ __device__ XVector3<T> operator *(T lhs, const XVector3<T>& rhs) { XVector3<T> r(rhs); r *= lhs; return r; } template <typename T> __host__ __device__ bool operator==(const XVector3<T>& lhs, const XVector3<T>& rhs) { return (lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z); } 可以存储任何类型的数据,这是教程中的代码

Queue

然后我修改了# queue.pyx # distutils: sources = c-algorithms/src/queue.c # distutils: include_dirs = c-algorithms/src/ cimport cqueue cdef class Queue: """A queue class for C integer values. >>> q = Queue() >>> q.append(5) >>> q.peek() 5 >>> q.pop() 5 """ cdef cqueue.Queue* _c_queue def __cinit__(self): self._c_queue = cqueue.queue_new() if self._c_queue is NULL: raise MemoryError() def __dealloc__(self): if self._c_queue is not NULL: cqueue.queue_free(self._c_queue) cpdef append(self, int value): if not cqueue.queue_push_tail(self._c_queue, <void*> value): raise MemoryError() # The `cpdef` feature is obviously not available for the original "extend()" # method, as the method signature is incompatible with Python argument # types (Python does not have pointers). However, we can rename # the C-ish "extend()" method to e.g. "extend_ints()", and write # a new "extend()" method that provides a suitable Python interface by # accepting an arbitrary Python iterable. cpdef extend(self, values): for value in values: self.append(value) cdef extend_ints(self, int* values, size_t count): cdef int value for value in values[:count]: # Slicing pointer to limit the iteration boundaries. self.append(value) cpdef int peek(self) except? -1: cdef int value = <Py_ssize_t> cqueue.queue_peek_head(self._c_queue) if value == 0: # this may mean that the queue is empty, # or that it happens to contain a 0 value if cqueue.queue_is_empty(self._c_queue): raise IndexError("Queue is empty") return value cpdef int pop(self) except? -1: if cqueue.queue_is_empty(self._c_queue): raise IndexError("Queue is empty") return <Py_ssize_t> cqueue.queue_pop_head(self._c_queue) def __bool__(self): return not cqueue.queue_is_empty(self._c_queue)

的一些代码
queue.pyx

但是当使用# queue.pyx # distutils: sources = c-algorithms/src/queue.c # distutils: include_dirs = c-algorithms/src/ from cpython.ref cimport PyObject cimport cqueue cdef class Queue: """A queue class for C integer values. >>> q = Queue() >>> q.append(5) >>> q.peek() 5 >>> q.pop() 5 """ cdef cqueue.Queue* _c_queue def __cinit__(self): self._c_queue = cqueue.queue_new() if self._c_queue is NULL: raise MemoryError() def __dealloc__(self): if self._c_queue is not NULL: cqueue.queue_free(self._c_queue) cdef append(self, void* value): if not cqueue.queue_push_tail(self._c_queue, <void*> value): raise MemoryError() # The `cpdef` feature is obviously not available for the original "extend()" # method, as the method signature is incompatible with Python argument # types (Python does not have pointers). However, we can rename # the C-ish "extend()" method to e.g. "extend_ints()", and write # a new "extend()" method that provides a suitable Python interface by # accepting an arbitrary Python iterable. cpdef extend(self, values): cdef void * ptr; for value in values: ptr = <void*>value self.append(ptr) cpdef extend_ints(self, int* values, size_t count): cdef PyObject* ptr for value in values[:count]: # Slicing pointer to limit the iteration boundaries. ptr = <PyObject*> value self.append(ptr) def __bool__(self): return not cqueue.queue_is_empty(self._c_queue) 进行构建时,它会报告

python3.6 setup.py build_ext -i

如何修复代码和修改功能Compiling queue.pyx because it changed. [1/1] Cythonizing queue.pyx Error compiling Cython file: ------------------------------------------------------------ ... cdef void * ptr; for value in values: ptr = <void*>value self.append(ptr) cpdef extend_ints(self, int* values, size_t count): ^ ------------------------------------------------------------ queue.pyx:45:10: Cannot convert 'int *' to Python object Traceback (most recent call last): File "setup.py", line 6, in <module> ext_modules = cythonize([Extension("queue", ["queue.pyx"])]) File "/Users/me/Library/Python/3.6/lib/python/site-packages/Cython/Build/Dependencies.py", line 1026, in cythonize cythonize_one(*args) File "/Users/me/Library/Python/3.6/lib/python/site-packages/Cython/Build/Dependencies.py", line 1146, in cythonize_one raise CompileError(None, pyx_file) Cython.Compiler.Errors.CompileError: queue.pyx peek的代码?

0 个答案:

没有答案