2014-07-03 4 views
7

मैं एक सी ++ लाइब्रेरी को पाइथन में बेनकाब करने के लिए साइथन का उपयोग कर रहा हूं, सभी रैपर ऑब्जेक्ट्स और फ़ंक्शन को आंतरिक मॉड्यूल _pydynd में डालकर, फिर इन्हें एक अलग पायथन मॉड्यूल के माध्यम से उजागर कर रहा हूं।
मैं dynd.nd.array की तरह दिखने के लिए, इन एक्सटेंशन वर्गों में दिखाई देने वाले मॉड्यूल और क्लास के नाम को नियंत्रित करना चाहता हूं, उदाहरण के लिए, _pydynd.w_array की बजाय, जो रैपर वर्ग का आंतरिक नाम है। क्या साइथन के पास ऐसा करने के लिए एक तंत्र है?मैं साइथन सीडीएफ कक्षा के मॉड्यूल/नाम को कैसे नियंत्रित करूं?

मुझे उम्मीद है कि आप अपनी परिभाषा लिखते समय सी/सी ++ कार्यों का नाम कैसे बदल सकते हैं, लेकिन मेरी खोज सूखी हो गई है। उत्पन्न सी ++ कोड जो अलग होना चाहिए यहाँ tp_name लाइन है:

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*/ 

अद्यतन:

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' 

उत्तर

0

मेरे पास है:

अगर मैं सीधे वस्तुओं का नाम बदलने की कोशिश करते हैं, यहाँ क्या होता है आपकी समस्या के लिए आंशिक समाधान, आप स्थानांतरित कर सकते हैं या क्या आपको अपनी __ init__.py फ़ाइल में एक समर्पित नेमस्पेस में बेहतर आयात चीजें कहनी चाहिए।

शुरू की सुविधा देता है, तो आप एक lib, जो निम्नलिखित बातें है है:

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

अब मैं सी चीज़ें से अधिक को कॉपी करके इस से बाहर मेरे अपने lib बनाया। अपने __ init__.py अपने newmodule में पाया में आप कुछ इस तरह कर सकते हैं:

__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)) 

आप वार्स से बातों पर पुनरावृति हैं (पुस्तकालय) आप भी बातें ही नाम बदल सकते हैं, लेकिन मैं तो यह प्रयास नहीं किया है दूर। अद्यतन() को एक शब्दकोश की आवश्यकता है और आप लेआउट में अपनी पसंद का एक शब्दकोश पास कर सकते हैं।

आप का उपयोग कंसोल पर इसके साथ प्रयोग कर सकते हैं (मुझे लगता है कि यह आपके लिए एक समाधान है):

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'> 

पुनश्च: मैं अपने वर्गों का पर्दाफाश करने को बढ़ावा देने का उपयोग कर रहा :: अजगर, लेकिन यह सिर्फ एक है cpython सामान के लिए रैपर।

+0

हाँ, मैं इस तरह की बातें पहले से ही कर रहा हूँ, लेकिन मैं __name__ और __module__ वस्तुओं पर अलग होना चाहते हैं, तो वे जनता के साथ मेल खाते हैं इंटरफ़ेस – mwiebe

2

साइथन-0.21 मॉड्यूल नाम सेट करने के लिए __init__.py फ़ाइल के सापेक्ष आपकी .pyx फ़ाइल के स्थान का उपयोग करने लगता है।

फ़ाइल लेआउट के लिए

jmap/__init__.py 
jmap/client.pyx 

cython के संकलक के उत्पादन __init__.py परिवर्तन इस मूल्य का स्थान ले जाकर

#define __Pyx_MODULE_NAME "jmap.client" 

भी शामिल है। यह जानकारी साइथन दस्तावेज में हो सकती है, लेकिन मुझे यह नहीं मिला।

चर्चा

यह उदा करने का अधिकार प्राप्त करने के लिए महत्वपूर्ण है सही ढंग से अचार कक्षाएं। विशेष रूप से इसके नाम की एक मॉड्यूल की अवधारणा सममित होनी चाहिए कि आप इसे कैसे आयात करते हैं। यह स्पष्ट प्रतीत होता है, लेकिन साइथन में तोड़ना आसान है।

अच्छा

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

बुरा

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

मैंने सिर्फ _pydynd.pyx के बजाय साइथन .pyx dynd._pydynd.pyx नामकरण करके, अचार की चीज़ को काम करने में कामयाब रहा है। इसका अभी भी मतलब है कि "dynd.nd.array" के बजाय इसका नाम "dynd._pydynd.w_array" है, जैसा कि मैं पसंद करता हूं। – mwiebe

संबंधित मुद्दे