2010-02-13 13 views
16

मैं रनटाइम पर .py फ़ाइल लोड करना चाहता हूं।लोड पायथन कोड

var1=value 
var2=value 
predicate_function=func line : <return true or false> 

एक बार इस फ़ाइल भरी हुई है, मैं var1, var2 और predicate_function उपयोग करने में सक्षम होना चाहते हैं: यह .py फ़ाइल मूल रूप से निम्न स्वरूप के साथ एक कॉन्फ़िग फ़ाइल है। प्रत्येक पंक्ति के लिए, मैं इसे पूर्वानुमान कार्य में पास कर दूंगा, और यदि यह झूठी वापसी करता है, तो मैं इसे अनदेखा कर दूंगा।

किसी भी मामले में, मुझे यकीन नहीं है कि रनटाइम पर एक पायथन फ़ाइल कैसे लोड करें और इसके चर का उपयोग कैसे करें।

स्पष्टीकरण: इनमें से कोई भी कॉन्फ़िगरेशन फ़ाइलें हो सकती हैं जिन्हें मुझे मुख्य कार्यक्रम में पास करने की आवश्यकता है और मैं रनटाइम तक उनके नाम नहीं जानूंगा। Google मुझे बताता है कि मुझे __import__ का उपयोग करना चाहिए। मुझे यकीन नहीं है कि उस विधि का सही तरीके से उपयोग कैसे करें और फिर आयात की गई फ़ाइल के चर का उपयोग करें।

उत्तर

10

आपको केवल आयात को गतिशील रूप से निर्दिष्ट करने और फिर गतिशील रूप से चरों पर पहुंचने में सक्षम होना चाहिए।

मान लें कि आपका कॉन्फ़िग फ़ाइल bar.py है और इस तरह दिखता है:

x = 3 
y = 4 
def f(x): return (x<4) 

फिर अपने कोड इस तरह दिखना चाहिए:

bar f <function f at 0x7f2354eb4cf8> 
bar x 3 
bar y 4 
:

import sys 

# somehow modnames should be a list of strings that are the names of config files 
# 
# you can do this more dynamically depending on what you're doing                          
modnames = ['bar'] 

for modname in modnames: 
    exec('import %s' % modname) 

for modname in modnames: 
    mod = sys.modules[modname] 
    for k in mod.__dict__: 
    if k[:2] != '__': 
     print modname, k, mod.__dict__[k] 

मैं इस आउटपुट प्राप्त

फिर आपके पास कम से कम सभी चर और फ़ंक्शन हैं। मुझे अनुमानित कार्यों से जो कुछ चाहिए था वह काफी नहीं मिला, लेकिन हो सकता है कि आप इसे अपने आप प्राप्त कर सकें।

+0

पूरी तरह से काम किया, धन्यवाद अग्रदूत! – Shahbaz

1

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

यानी के रूप में यह आयात करते हैं।

main.py:

import config 
print config.var1 

config.py:

var="var12" 
var2 = 100.5 
+0

मेरे पास ऐसी कोई भी कॉन्फ़िगरेशन फ़ाइलें हो सकती हैं, इसलिए मैं केवल "आयात कॉन्फ़िगर फ़ाइल" नहीं कर सकता। अन्यथा यह सबसे आसान समाधान होगा :) – Shahbaz

2

अजगर 2.*, में execfile काम करता है (मैं एक विशिष्ट शब्दकोश गुजर करने की सलाह देते हैं और वहाँ से चर तक पहुँचने - नोट के रूप में दस्तावेज़ों में कहते हैं, execfile कॉलिंग फ़ंक्शन के locals() शब्दकोश को प्रभावित नहीं कर सकता है)।

अजगर 3.* में, execfile निकाला जा चुका है, इसलिए, कर के बजाय:

with open('thefile.py') as f: 
    exec(f.read(), somedict) 
7

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

कॉन्फ़िगरेशन के लिए पाइथन फ़ाइल का उपयोग करने के लिए बेहतर नहीं होगा, बल्कि बिल्टिन मॉड्यूल ConfigParser या जेएसओएन जैसे क्रमिक प्रारूप का उपयोग करने के लिए बेहतर होगा। इस प्रकार आपकी कॉन्फ़िगरेशन फ़ाइलें मनमाने ढंग से (संभावित रूप से दुर्भावनापूर्ण) कोड निष्पादन की अनुमति नहीं देती हैं, लोगों को आपके प्रोग्राम को कॉन्फ़िगर करने के लिए पाइथन को जानने की आवश्यकता नहीं होती है, और आसानी से प्रोग्रामिक रूप से बदला जा सकता है।

+0

दरअसल कारण मैं अपनी कॉन्फ़िगरेशन को एक पाइथन फ़ाइल बना रहा हूं क्योंकि मैं कॉन्फ़िगरेशन फ़ाइल को कुछ (predicate) फ़ंक्शन रखना चाहता हूं। अन्यथा मैं एक पाठ फ़ाइल में पढ़ना आसान था, तारों को विभाजित करता हूं और एक धक्का में पढ़ता हूं। – Shahbaz

7

यदि आयातित मॉड्यूल नियमित खोज पथ पर है, तो आप __import__ का उपयोग कर सकते हैं।

यदि आपको फाइल सिस्टम में मनमाने ढंग से पथ से मॉड्यूल लोड करने की आवश्यकता है, तो imp.load_module का उपयोग करें।

मनमानी उपयोगकर्ता-निर्दिष्ट कोड लोड करने के सुरक्षा प्रभावों पर विचार करना सुनिश्चित करें।

+0

+1 संक्षिप्त और सरल (= पायथनिक) – 0xc0de

14

जैसा कि python official documentation में लिखा गया है, यदि आप सिर्फ नाम से मॉड्यूल आयात करना चाहते हैं, तो आप __import__ का उपयोग करने के बाद sys.modules शब्दकोश में इसे देख सकते हैं।

आपके विन्यास मान लें कि myproject.mymodule में है, तो आप उस तरह करना होगा:

module_name = 'myproject.mymodule' 

import sys 
__import__(module_name) 
mymodule = sys.modules[module_name] 

# Then you can just access your variables and functions 
print mymodule.var1 
print mymodule.var2 
# etc... 

तुम भी __import__ बयान की वापसी मान का उपयोग कर सकते हैं, लेकिन आप पूरी तरह से how python works with namespaces and scopes को समझने के लिए होगा।

+2

mmh, nope, मेरे उदाहरण में, यह 'myproject' मॉड्यूल लौटाएगा, न कि 'myproject.mymodule'। सीधे डॉक्टर से: _ जब नाम परिवर्तक फॉर्म पैकेज का है। मॉड्यूल, आमतौर पर, शीर्ष-स्तरीय पैकेज (पहला बिंदु तक नाम) लौटाया जाता है, न कि name._ द्वारा नामित मॉड्यूल –

2

मैं थोड़े पार्टी के लिए देर हो रही है, लेकिन मैं फिर भी एक विकल्प के जवाब पेश करने के लिए करना चाहते हैं।

आप वैश्विक मॉड्यूल नाम स्थान को प्रभावित किए बिना कोड आयात करना चाहते हैं, तो आप एक अनाम मॉड्यूल (types.ModuleType का प्रयोग करके) बनाने और इसे में मनमाने ढंग से कोड को लोड (compile और exec का प्रयोग करके) कर सकते हैं। उदाहरण के लिए, इस तरह के लिए:

import types 

filename = "/path/to/your/file.py" 
with open(filename) as fp: 
    code = compile(fp.read(), filename, "exec") 
config_module = types.ModuleType("<config>") 
exec code in config_module.__dict__ 

फिर आप के रूप में config_module.var1, & ग चर पहुँच सकते हैं।

0

अजगर संस्करण के बाद से स्पष्ट रूप से नहीं उल्लेख किया गया है, यह उनका कहना है कि इम्प मॉड्यूल importlib मॉड्यूल के पक्ष में नए अजगर संस्करणों में पदावनत किया गया है लायक है। Example here.

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