2014-07-03 26 views
7

Bir C++ kitaplığını python'a göstermek için cython kullanıyorum, tüm sarıcı nesneleri ve işlevleri bir iç modülde _pydynd içine koyarak, bunları farklı bir python modülünden göstererek.
Bu uzantı sınıflarında görünen modül ve sınıfın adını denetlemek istiyorum, örneğin dynd.nd.array, örneğin, sarıcı sınıfının iç adı olan _pydynd.w_array yerine. Cython'un bunu yapacak bir mekanizması var mı?Bir cython cdef sınıfının modülünü/adını nasıl kontrol ederim?

Tanımlarını yazarken C/C++ işlevlerini nasıl yeniden adlandırabileceğinize benzer bir şey bulmayı umdum, ancak aramalarım kurudu. farklı olmalıdır oluşturulan C++ kod burada tp_name çizgidir:

static PyTypeObject __pyx_type_7_pydynd_w_array = { 
    PyVarObject_HEAD_INIT(0, 0) 
    __Pyx_NAMESTR("_pydynd.w_array"), /*tp_name*/ 
    sizeof(struct __pyx_obj_7_pydynd_w_array), /*tp_basicsize*/ 

GÜNCELLEME:

In [103]: nd.array.__name__ 
Out[103]: 'w_array' 

In [104]: nd.array.__module__ 
Out[104]: 'dynd._pydynd' 

In [105]: nd.array.__name__ = "array" 
--------------------------------------------------------------------------- 
TypeError         Traceback (most recent call last) 
<ipython-input-105-73d9172a0216> in <module>() 
----> 1 nd.array.__name__ = "array" 

TypeError: can't set attributes of built-in/extension type 'dynd._pydynd.w_array' 

In [106]: nd.array.__module__ = "dynd.nd" 
--------------------------------------------------------------------------- 
TypeError         Traceback (most recent call last) 
<ipython-input-106-37f990658ede> in <module>() 
----> 1 nd.array.__module__ = "dynd.nd" 

TypeError: can't set attributes of built-in/extension type 'dynd._pydynd.w_array' 

cevap

0

Ben:

burada

doğrudan nesneleri adlandırmak çalışırsanız, böyle olur Sorunuz için kısmen bir çözüm, hareket edebilir ya da __ init__.py dosyanızdaki özel bir ad alanına daha iyi şeyler ithal edebiliriz.

module.libname.A (A is a class for e.g. or anything else) 
module.libname.B 
... 

Şimdi tings üzerinde kopyalayarak bu işten benim kendi lib oluşturuldu:

aşağıdaki şeyler vardır bir lib, var başlayalım. senin newmodule bulundu sizin __ init__.py olarak böyle bir şey yapabilirsiniz:

__import__("module."+libname) # this import will import the library in the current context 
globals().update(vars(module.libname)) 

# or use this 
library = import_("PathToLibAndFilename", "module.") 
globals().update(vars(library)) 

sen vars gelen şeye (kütüphane) ayrıca şeyler kendini yeniden adlandırabilirsiniz ama yani bu denemedim yineleme durumunda uzak. update() bir sözlüğe ihtiyaç duyar ve mizanpajda seçtiğiniz bir sözlüğü aktarabilirsiniz.

Sen (bunun senin için bir çözüm olduğunu düşünüyorum) kullanılarak konsolda işlevi deneyebilirsiniz

:

import(libName) 
globals().update({"testMe":vars(libName)["A"]}) # A is your class name from the library 
# then you can do: 
testMe 
# in my case this outputs something like this: <class 'libName.A'> 

PS: Ben sınıflarını sergilemek için :: piton boost kullanıyorum, ama sadece bir olduğunu sarıcı cpython şeyler.

+0

Evet, zaten bu gibi şeyler yapıyorum ama __name__ ve __module__ nesneler üzerinde farklı olmak istiyorlar, böylece kamuoyu ile eşleşecek arayüz – mwiebe

2

Cython-0.21, modülün adını ayarlamak için .pyx dosyasının konumunu __init__.py dosyasına göre kullanır. dosya düzeni için

jmap/__init__.py 
jmap/client.pyx 

Cython derleyici çıkış __init__.py değişikliklerin bu değer yerini hareketli

#define __Pyx_MODULE_NAME "jmap.client" 

içerir. Bu bilgi Cython belgelerinde olabilir, ancak bulamadım.

TARTIŞMA

Bu örneğin doğru almak önemlidir doğru sınıfları seç. Özellikle bir modülün isminin konsepti, onu nasıl içe aktardığınıza göre simetrik olmalıdır. Bu bariz görünüyor, ancak cython içinde kırılması kolaydır.

İyi

>>> from jmap.client import JMapError 
>>> JMapError 
<class 'jmap.client.JMapError'> 

Kötü

>>> import jmap 
>>> jmap.JMapError 
<class 'Client.client.JMapError'> 
+0

Sadece _pydynd.pyx yerine cython .pyx dynd._pydynd.pyx adını vererek, turşu işini yapmayı başardım. Bu yine de, tercih ettiğim gibi "dynd.nd.array" yerine "dynd._pydynd.w_array" ismine sahip olduğu anlamına gelir. – mwiebe

İlgili konular