2009-12-02 13 views
6

मुझे एक ज़िपफाइल (पीई 2 एक्सई संकुचित द्वारा निर्मित) से सभी मॉड्यूल (पूर्व-संकलित) को स्मृति में पढ़ने की आवश्यकता है और फिर उन्हें सभी लोड करें। मुझे पता है कि यह ज़िपफाइल से सीधे लोड करके किया जा सकता है लेकिन मुझे उन्हें स्मृति से लोड करने की आवश्यकता है। कोई विचार? (मैं विंडोज़ पर पायथन 2.5.2 का उपयोग कर रहा हूं) टीआईए स्टीवस्मृति से संकलित पायथन मॉड्यूल कैसे लोड करें?

+0

क्या आप कुछ और पृष्ठभूमि दे सकते हैं? कोड को स्मृति में पहली जगह में लोड करने की आवश्यकता क्यों है? ज़िप फ़ाइल से लोड क्यों नहीं हो रहा है? – Ber

उत्तर

30

यह इस बात पर निर्भर करता है कि आपके पास "मॉड्यूल (प्री-कंपाइल)" जैसा है। के, मान लें कि यह वास्तव में एक .pyc फ़ाइल की सामग्री है, जैसे ciao.pyc करते हैं के रूप में द्वारा बनाया गया:

$ cat>'ciao.py' 
def ciao(): return 'Ciao!' 
$ python -c'import ciao; print ciao.ciao()' 
Ciao! 

IOW, इस प्रकार का निर्माण होने ciao.pyc, का कहना है कि तुम अब क्या:

$ python 
Python 2.5.1 (r251:54863, Feb 6 2009, 19:02:12) 
[GCC 4.0.1 (Apple Inc. build 5465)] on darwin 
Type "help", "copyright", "credits" or "license" for more information. 
>>> b = open('ciao.pyc', 'rb').read() 
>>> len(b) 
200 

और अपने लक्ष्य के लिए है एक आयात योग्य मॉड्यूल ciao पर उस बाइट स्ट्रिंग b से जाएं।

>>> import marshal 
>>> c = marshal.loads(b[8:]) 
>>> c 
<code object <module> at 0x65188, file "ciao.py", line 1> 

यह कैसे आप .pyc द्विआधारी सामग्री से कोड वस्तु मिलता है: यहाँ कैसे। संपादित करें: यदि आप उत्सुक हैं, तो पहले 8 बाइट एक "जादू संख्या" और एक टाइमस्टैम्प हैं - यहां की आवश्यकता नहीं है (जब तक कि आप उन्हें संवेदना नहीं चाहते हैं- अगर जांच की जाती है तो अपवाद बढ़ाएं, लेकिन ऐसा लगता है कि यह दायरे से बाहर है प्रश्न; marshal.loads वैसे भी उठाएगा यदि यह भ्रष्ट स्ट्रिंग का पता लगाता है)।

फिर

:

>>> import types 
>>> m = types.ModuleType('ciao') 
>>> import sys 
>>> sys.modules['ciao'] = m 
>>> exec c in m.__dict__ 

यानी: एक नए मॉड्यूल वस्तु बनाने के लिए, sys.modules में इसे स्थापित है, इसके __dict__ में कोड वस्तु को क्रियान्वित करते हुए पॉप्युलेट करें। संपादित: जिस क्रम में आप sys.modules प्रविष्टि और exec मामलों करते हैं और केवल यदि आप परिपत्र आयात हो सकता है - लेकिन, इसी क्रम अजगर के अपने import है सामान्य रूप से उपयोग करता है, तो यह बेहतर है यह नकल करने के लिए (जो कोई विशेष है कमियां)।

आप कई तरीकों से "नया मॉड्यूल ऑब्जेक्ट" बना सकते हैं (उदाहरण के लिए, मानक लाइब्रेरी मॉड्यूल जैसे new और imp) में फ़ंक्शंस से, लेकिन "उदाहरण प्राप्त करने के लिए प्रकार को कॉल करें" इन दिनों सामान्य पायथन तरीका है, और उस प्रकार से प्राप्त करने के लिए सामान्य स्थान (जब तक कि इसमें अंतर्निर्मित नाम न हो या अन्यथा यह पहले से ही आसान हो) मानक लाइब्रेरी मॉड्यूल types से है, इसलिए मैं यही सलाह देता हूं।

अब

, अंत:

>>> import ciao 
>>> ciao.ciao() 
'Ciao!' 
>>> 

... आप मॉड्यूल आयात और अपने कार्यों, कक्षाओं का उपयोग कर सकते हैं, और इतने पर। अन्य import (और from) बयान तो sys.modules['ciao'] के रूप में मॉड्यूल मिलेगा, तो आप आपरेशनों के इस क्रम को दोहराने की जरूरत नहीं होगी (वास्तव में आप जरूरत यह पिछले import यहां बयान करता है, तो सब आप चाहते हैं मॉड्यूल सुनिश्चित करने के लिए है नहीं है कहीं और से आयात के लिए उपलब्ध है - मैं इसे केवल यह दिखाने के लिए जोड़ रहा हूं ;-)।

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

यह भी ध्यान दें कि यह "मॉड्यूल को कई बार स्मृति से लोड करने" के मामलों में जो भी आप चाहते हैं, हो सकता है या नहीं (यह हर बार मॉड्यूल का पुनर्निर्माण करता है; आप sys.modules जांचना चाहेंगे और बस सबकुछ छोड़ सकते हैं मॉड्यूल पहले से ही है) और विशेष रूप से जब इस तरह के दोहराए गए "स्मृति से लोड" कई धागे से होता है (ताले की आवश्यकता होती है - लेकिन, एक बेहतर आर्किटेक्चर कार्य करने के लिए समर्पित एक समर्पित धागा है, अन्य मॉड्यूल के माध्यम से इसके साथ संवाद कर रहा है एक क़तार)।

अंत में, इस कार्यक्षमता को एक पारदर्शी "आयात हुक" के रूप में स्थापित करने के बारे में कोई चर्चा नहीं है, जो स्वचालित रूप से import स्टेटमेंट इंटर्नल्स के तंत्र में शामिल हो जाता है - यह भी संभव है, लेकिन वास्तव में आप जो भी पूछ रहे हैं के बारे में, यहां भी, मुझे उम्मीद है कि आप चीजों को सरल तरीके से कर कर अपने जीवन को सरल बना सकते हैं, क्योंकि यह उत्तर रूपरेखा है।

+1

बस उत्सुक है, क्या यह .pyd फ़ाइलों के लिए भी काम करेगा? – YOU

+1

मुझे एक ही आवश्यकता थी और समाधान की तलाश में था, धन्यवाद एलेक्स :) – Parthan

+0

@ एसमार्क, नहीं, '.pyc' या' .pyo' केवल - '.pyd की अनिवार्य रूप से' .dll ' एक झूठे नाम के तहत और वर्तमान ** पूरी तरह से ** अलग-अलग समस्याएं। @Technofreak, आपका स्वागत है! -) –

9

, संकलित पायथन फ़ाइल हम नए स्रोत की जांच करने के

  1. जादुई संख्या (4 बाइट्स) प्रकार और अजगर के संस्करण का निर्धारण करने के लिए,
  2. टाइमस्टैम्प (4 बाइट्स) से मिलकर बनता है
  3. मार्शल कोड वस्तु।

मॉड्यूल आपको imp.new_module() साथ मॉड्यूल वस्तु बनाने, नए मॉड्यूल के नाम स्थान में unmashaled कोड निष्पादित और sys.modules में रख लिए है लोड करने के लिए। नमूना कार्यान्वयन में नीचे:

import sys, imp, marshal 

def load_compiled_from_memory(name, filename, data, ispackage=False): 
    if data[:4]!=imp.get_magic(): 
     raise ImportError('Bad magic number in %s' % filename) 
    # Ignore timestamp in data[4:8] 
    code = marshal.loads(data[8:]) 
    imp.acquire_lock() # Required in threaded applications 
    try: 
     mod = imp.new_module(name) 
     sys.modules[name] = mod # To handle circular and submodule imports 
           # it should come before exec. 
     try: 
      mod.__file__ = filename # Is not so important. 
      # For package you have to set mod.__path__ here. 
      # Here I handle simple cases only. 
      if ispackage: 
       mod.__path__ = [name.replace('.', '/')] 
      exec code in mod.__dict__ 
     except: 
      del sys.modules[name] 
      raise 
    finally: 
     imp.release_lock() 
    return mod 

अद्यतन: कोड संकुल ठीक से संभाल करने के लिए अद्यतन किया गया है।

ध्यान दें कि लोड किए गए मॉड्यूल के अंदर आयात को संभालने के लिए आपको आयात हुक इंस्टॉल करना होगा। ऐसा करने का एक तरीका आपके खोजक को sys.meta_path में जोड़ रहा है। अधिक जानकारी के लिए PEP302 देखें।

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