2013-03-08 10 views
14

में आयात स्थिरांक मैं इस प्रश्न का एक सरल उत्तर ढूंढ रहा हूं, लेकिन ऐसा लगता है कि मुझे कोई नहीं मिल रहा है। मैं किसी बाहरी पुस्तकालय से दूर रहना पसंद करूंगा जो पहले से ही पायथन 2.6/2.7 में शामिल नहीं है।.h फ़ाइल से python

2 सी हेडर फाइल जो निम्न के समान है:

//constants_a.h 
const double constant1 = 2.25; 
const double constant2 = -0.173; 
const int constant3 = 13; 

...

//constants_b.h 
const double constant1 = 123.25; 
const double constant2 = -0.12373; 
const int constant3 = 14; 

...

और मैं एक अजगर वर्ग कि मैं आयात करना चाहते हैं है इन स्थिरांक में:

#pythonclass.py 
class MyObject(object): 
    def __init(self, mode): 
     if mode is "a": 
      # import from constants_a.h, like: 
      # self.constant1 = constant1 
      # self.constant2 = constant2 
     elif mode is "b": 
      # import from constants_b.h, like: 
      # self.constant1 = constant1 
      # self.constant2 = constant2 

...

मैं ग कोड है जो स्थिरांक के रूप में अच्छी तरह से उपयोग करता है, और इस जैसा दिखता है:

//computations.c 
#include <stdio.h> 
#include <math.h> 
#include "constants_a.h" 

// do some calculations, blah blah blah 

मैं कैसे पायथन वर्ग में हेडर फाइल से स्थिरांक आयात कर सकते हैं?

शीर्षलेख फ़ाइलों constants_a.h और constants_b.h का कारण यह है कि मैं स्थिरांक का उपयोग करके अधिकांश गणना करने के लिए पायथन का उपयोग कर रहा हूं, लेकिन एक बिंदु पर मुझे अधिक अनुकूलित गणना करने के लिए सी का उपयोग करने की आवश्यकता है। इस बिंदु पर मैं सी कोड को पायथन में सी कोड लपेटने के लिए उपयोग कर रहा हूं। मैं स्थिरांक को कोड से दूर रखना चाहता हूं, अगर मुझे उन्हें अपडेट या बदलने की ज़रूरत है, और मेरा कोड भी अधिक क्लीनर बनाएं। मुझे नहीं पता कि यह ध्यान देने में मदद करता है कि मैं न्यूमपी का भी उपयोग कर रहा हूं, लेकिन इसके अलावा, कोई अन्य गैर-मानक पायथन एक्सटेंशन नहीं। मैं इस कार्यक्रम के डिजाइन या वास्तुकला के संबंध में किसी भी सुझाव के लिए भी खुला हूं।

+0

इस तरह के देर से प्रतिक्रिया के लिए खेद है। मेरे पास एक नई, जरूरी परियोजना थी जिस पर मैं काम कर रहा था, और उसे बैकबर्नर पर रखना पड़ा। फिलहाल, मैं कांग्रेस और एमिलियो के उत्तरों के बीच फंस गया हूं। मैं शायद कांग्रेस के ctypes कार्यान्वयन की ओर अधिक दुबला होगा, लेकिन मुझे अभी भी वास्तव में 're' का उपयोग कर पार्सिंग विधि पसंद है। सभी महान विचारों के लिए धन्यवाद! –

उत्तर

12

मैं फ़ाइलों से बाहर की जाने वाली जानकारी को पार्स करने के लिए नियमित अभिव्यक्तियों (re मॉड्यूल) का उपयोग करने की सलाह देता हूं।

एक पूर्ण सी पार्सर बनाना बहुत बड़ा होगा, लेकिन यदि आप केवल चर का उपयोग करते हैं और फ़ाइल उचित रूप से सरल/अनुमानित/नियंत्रण में है, तो आपको जो लिखना है वह सरल है।

बस 'गेटचा' कलाकृतियों के लिए देखें जैसे टिप्पणी-आउट कोड!

+3

[टूल्स/स्क्रिप्ट/h2py.py] (http://hg.python.org/cpython/log/70274d53c1dd/Tools/scripts/h2py.py) स्क्रिप्ट पर एक नज़र डालें, 1 99 2 से संशोधित। – eryksun

+0

धन्यवाद एमिलियो और eryksun। जब तक मैंने कांग्रेस का जवाब नहीं देखा, मैं विश्वास कर रहा था कि यह जाने का रास्ता था। इस उद्देश्य के लिए एक छोटा पार्सर लिखना भी एक अच्छा अभ्यास होगा। –

+0

@ मनीला ट्रिला: आपका बहुत स्वागत है।मैंने कांग्रेस के जवाब को पढ़ और उखाड़ फेंक दिया है, यह बहुत ही जानकारीपूर्ण है। चूंकि इस समय के बाद एक बेहतर उत्तर आने की संभावना नहीं है, मेरा सुझाव है कि आप कांग्रेस को स्वीकार्य मानते हैं। –

1

मैं एमिलियो को अप-वोट दूंगा, लेकिन मुझे प्रतिनिधि की कमी है!

हालांकि आपने अन्य गैर-मानक पुस्तकालयों से बचने का अनुरोध किया है, लेकिन आप साइथन (साइथन: सी-एक्सटेंशन के लिए पायथन www.cython.org/) पर एक नज़र डालना चाहेंगे, जो पाइथन कोडिंग की लचीलापन प्रदान करता है और सी/सी ++ के निष्पादन की कच्ची गति - संकलित कोड।

इस तरह आप सब कुछ के लिए नियमित पायथन का उपयोग कर सकते हैं, लेकिन इसके अंतर्निर्मित सी-प्रकारों का उपयोग करके कोड के महंगे तत्वों को संभाल सकते हैं। फिर आप अपने पायथन कोड को .c फ़ाइलों में भी परिवर्तित कर सकते हैं (या केवल बाहरी सी-पुस्तकालयों को स्वयं लपेटें।), जिसे तब बाइनरी में संकलित किया जा सकता है। मैंने संख्यात्मक दिनचर्या के लिए ऐसा करने के लिए 10x स्पीड-अप हासिल कर लिया है। मुझे यह भी विश्वास है कि न्यूमपी इसका इस्तेमाल करता है।

+0

वैसे मैंने मूल रूप से साइथन में अपना कोड लागू किया, लेकिन जैसा कि मैंने अपने प्रश्न में कहा है, मैं पोर्टेबिलिटी बनाए रखने के लिए अब सीटीपी का उपयोग कर रहा हूं। समस्या यह है कि साइथन मानक पायथन पुस्तकालय में उपलब्ध नहीं है, लेकिन ctypes है। लेकिन आप सही हैं, साइथन अद्भुत और उपयोग करने में बहुत आसान है। हालांकि मुझे साइथॉन की तुलना में कुछ माइक्रोसॉन्ड तेजी से होने के लिए सीटीपीई मिलीं। –

3

मैं हेडर में निरंतर मानों को संग्रहीत करने के बजाय, पायथन और सी प्रोग्राम दोनों द्वारा पठनीय कुछ प्रकार की कॉन्फ़िगरेशन फ़ाइल का उपयोग करने की अनुशंसा करता हूं। जैसे एक सरल सीएसवी, आईएनआई-फाइल, या यहां तक ​​कि 'कुंजी: मान' जोड़े का अपना सरल प्रारूप भी।और प्रत्येक बार जब आप मूल्यों में से एक को बदलना चाहते हैं तो सी प्रोग्राम को पुन: संकलित करने की आवश्यकता नहीं होगी :)

+0

यह बहुत अच्छा लगता है, लेकिन मुझे लगता है कि मुझे सी प्रोग्राम के लिए एक पार्सर बनाना होगा, जिसे मैं नहीं करना चाहता, या लिबकॉन्फिग जैसी लाइब्रेरी का उपयोग करना चाहता हूं, जिसे मैं नहीं करना चाहता हूं। यह अच्छा होगा, हालांकि, हर बार सी प्रोग्राम को पुन: संकलित करने की आवश्यकता नहीं है। क्या आपके पास इस कॉन्फ़िगरेशन फ़ाइल के लिए संभवतः एक उदाहरण है? –

+0

उदाहरण के रूप में एक JSON- स्वरूपित कॉन्फ़िगरेशन। पायथन की मानक लाइब्रेरी द्वारा समर्थित और सी के लिए कई कार्यान्वयन http://www.json.org/ –

11

सामान्य रूप से परिभाषित करना सी हेडर फ़ाइल में चर खराब शैली है। हेडर फ़ाइल केवल ऑब्जेक्ट्स घोषित करनी चाहिए, उचित ".c" स्रोत कोड फ़ाइल के लिए उनकी परिभाषा छोड़कर।

एक बात आप क्या करना चाहते हो सकता है extern const whatever_type_t foo; तरह पुस्तकालय-वैश्विक स्थिरांक की घोषणा करने और अपने सी कोड में परिभाषित (या "लागू") उन्हें (यानी उन्हें मान निर्दिष्ट) कहीं (आप केवल एक बार ऐसा सुनिश्चित करने के लिए है)।

वैसे भी, कैसे को अनदेखा करते हैं। बस मान लीजिए कि आपने पहले से ही स्थिरांक को परिभाषित कर दिया है और अपने प्रतीकों को अपनी साझा ऑब्जेक्ट फ़ाइल "libfoo.so" में दिखाई दिया है। मान लीजिए कि आप अपने पायथन कोड से प्रतीक को extern const double pi = 3.1415926; के रूप में परिभाषित करना चाहते हैं।

अब आप आम तौर पर अपनी वस्तु फ़ाइल पायथन में ctypes इस तरह का उपयोग करके लोड:

>>> import ctypes 
>>> libfoo = ctypes.CDLL("path/to/libfoo.so") 

लेकिन तब आप ctypes सोचता libfoo.pi एक समारोह, नहीं निरंतर डेटा के लिए एक प्रतीक है देखेंगे! कास्टिंग क्या ctypes सोचता है कि एक समारोह वापस एक नंबर करने के लिए है -

>>> libfoo.pi 
<_FuncPtr object at 0x1c9c6d0> 

अपने मूल्य पहुंचने के लिए, आप कुछ नहीं बल्कि अजीब क्या करना है।

>>> pi = ctypes.cast(foo.pi, ctypes.POINTER(ctypes.c_double)) 
>>> pi.contents.value 
3.1415926 

सी शब्दजाल में, यह अस्पष्ट निम्नलिखित बात हो रहा से मेल खाती है: आप एक const double pi है, लेकिन किसी को केवल एक समारोह सूचक के माध्यम से इसका इस्तेमाल करने के लिए मजबूर करता आप:

typedef int (*view_anything_as_a_function_t)(void); 
view_anyting_as_a_function_t pi_view = &pi; 

आप किस विधि से करते हो pi के मान का उपयोग करने के लिए सूचक pi_view? आपने इसे const double * के रूप में वापस डाला और इसे अस्वीकार कर दिया: *(const double *)(pi_view)

तो यह सब बहुत अजीब है। हो सकता है कि मुझे कुछ याद आ रहा है लेकिन मुझे लगता है कि ctypes मॉड्यूल के डिजाइन द्वारा यह है - यह मुख्य रूप से विदेशी फ़ंक्शन को पर कॉल करने के लिए मुख्य रूप से "विदेशी" डेटा तक पहुंचने के लिए नहीं है। और एक लोड करने योग्य पुस्तकालय में शुद्ध डेटा प्रतीक निर्यात करना दुर्लभ रूप से दुर्लभ है।

और यदि यह स्थिरांक केवल सी मैक्रो परिभाषाएं हैं तो यह काम नहीं करेगा। सामान्य रूप से आप मैक्रो-डिफ़ाइंड डेटा को बाहरी रूप से एक्सेस नहीं कर सकते हैं। वे संकलित समय पर मैक्रो-विस्तारित हैं, जेनरेट की गई लाइब्रेरी फ़ाइल में कोई दृश्यमान प्रतीक नहीं छोड़ते हैं, जब तक आप अपने सी कोड में अपने मैक्रो मान भी निर्यात करते हैं।

+2

पर उपलब्ध हैं, ठीक है, मैंने इसे करने के लिए अजीब तरीके से पता चला: http://python.net/crew/theller /ctypes/tutorial.html#accessing-values-exported-from-dlls आप पाइथन कोड में 'pi = ctypes.c_double (libfoo," pi ") 'आज़मा सकते हैं; यह 'ctypes.c_double' उदाहरण देता है, और आप' pi.value' द्वारा इसके मान तक पहुंच सकते हैं। –

+0

धन्यवाद आपके बहुत विस्तृत उत्तर के लिए कांग्रेस। मुझे लगता है कि उदाहरणों के मूल्यों तक पहुंच मेरे काम के लिए उपयुक्त होगी। यह एक वास्तविक सॉफ्टवेयर रिलीज के बजाय एक वैज्ञानिक प्रयास है, इसलिए मैं आसानी और स्पष्टता के लिए जा रहा हूं। हालांकि, मैं उत्सुक हूं कि आप स्थिरांक को परिभाषित करने के लिए एक बेहतर शैली पर विचार करेंगे। ध्यान रखें कि ये स्थिरांक एक अलग फ़ाइल में होना चाहिए ताकि यह उनके मूल्यों को त्वरित रूप से संपादित या बदलने के लिए एक साधारण बात हो। –

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