2012-11-12 48 views
5

मुझे फ़ंक्शन के रूप में इनपुट स्ट्रिंग (डेटाबेस से) को संकलित करने और इसे चलाने की आवश्यकता है।एएसटी का उपयोग कर फ़ंक्शन के रूप में टेक्स्ट को संकलित कैसे करें?

कहो मैं पहले से ही इस समारोह को परिभाषित किया है:: यह विधि मैं वर्तमान में उपयोग करें

def foo(): 
    print "Yo foo! I am a function!" 

और स्ट्रिंग मैं डेटाबेस से में पढ़ा है कि मैं इस समारोह फोन करना चाहिए कहते हैं:

string_from_db = "foo()" 

मैं फिर एक फ़ंक्शन (जिसका नाम मैं नियंत्रित कर सकता हूं) बनाता हूं जो डेटाबेस से पढ़े गए फ़ंक्शन को लौटाता है:

my_func_string = "def doTheFunc():\n\t return " + string_from_db 

अब मैं स्ट्रिंग संकलन, और एक समारोह का नाम मैं प्रसंस्करण के लिए बाद में उपयोग करने के लिए यह सेट: Yo foo! I am a function!

मेरे प्रश्न:: ऊपर

exec my_func_string 
processor = doTheFunc 

मैं इसे कॉल कर सकते हैं बाद में processor() चल रहा है जो का दावा द्वारा "। संभावित प्रतिस्थापन"

############################################################### 
    # The following method for getting a function out of the text # 
    # in the database could potentially be replaced by using  # 
    # Python's ast module to obtain an abstract syntax tree and # 
    # put it inside of a function node       # 
    ############################################################### 

मैं इस बारे में अधिक जानना चाहते हैं: कोड के इस टुकड़े वहाँ एक टिप्पणी (एक लंबे खो डेवलपर द्वारा छोड़कर चला गया) मैंने एएसटी पर एक नज़र डाली है, लेकिन मैं इस बात पर बहुत उलझन में हूं कि यह मेरी मदद कैसे कर सकता है जो मैं ऊपर दिए गए कोड के साथ कर रहा हूं।

  1. एएसटी का उपयोग करके मैं वही चीज़ कैसे पूरा कर सकता हूं? या इस प्रक्रिया में एएसटी मेरी मदद कर सकता है?
  2. एएसटी का उपयोग करके कार्यान्वयन बेहतर है, और क्यों?
+5

आप अंधेरे जादू के क्षेत्र में रहें। –

+1

यदि आप स्ट्रिंग को सुरक्षित रखने के बारे में जानते हैं, तो 'exec' 'exec()' पर' ast' का उपयोग करने का कोई कारण नहीं है। पायथन दुभाषिया पहले से ही कार्य पदार्थों में पाइथन स्रोत कोड पार्सिंग लागू करता है, इसे दोहराना क्यों? – millimoose

+0

@ मिलिमुओस मैं 'निष्पादन' कार्यान्वयन के साथ जा रहा हूं, क्योंकि मुझे पता है कि मेरे तार सुरक्षित हैं। हालांकि, इस सवाल ने मुझे 'अस्थिर' के लिए बेहतर उपयोगों पर प्रकाश डाला है। धन्यवाद! – dinkelk

उत्तर

5

एएसटी एक ज्यादा सुरक्षित विकल्प है जब अविश्वस्त कोड का मूल्यांकन, कि, दुर्भावनापूर्ण निर्देश, eval या exec हो सकता है किसी भी अभिव्यक्ति निष्पादित कर सकते हैं जबकि दूसरी तरफ एएसटी, आप पार्स और अभिव्यक्ति खुद को मान्य, या निष्पादित करने के लिए अनुमति देता है ast.literal_eval का उपयोग करके एक सीमित अभिव्यक्ति, एक सैंडबॉक्स की तरह, जो केवल स्ट्रिंग्स, सूचियों, संख्याओं और कुछ अन्य चीजों की अनुमति देता है। यह सिर्फ एक सरल उदाहरण है:

import ast 
a = ast.literal_eval("[1,2,3,4]") //evaluate an expression safely. 

एक और उदाहरण है कि एक एएसटी में एक स्ट्रिंग को पार्स करता है:

import ast 
source = '2 + 2' 
node = ast.parse(source, mode='eval') 
ast.dump(node) 

यह प्रिंट:

Expression(body=BinOp(left=Num(n=2), op=Add(), right=Num(n=2))) 

एक बहुत अच्छा ट्यूटोरियल here और यह भी नहीं है documentation

+0

ग्रेट ट्यूटोरियल! मैं "अपने लिए अभिव्यक्ति को मान्य करने" के बारे में कैसे जाउंगा? मैं कैसे बता सकता हूं कि कोड खराब है या मेरी आवश्यकताओं को पूरा नहीं करता है? मान लीजिए कि मुझे छोटे कार्यों को संकलित करने की आवश्यकता होगी; मैं खुद को सरल तारों, सूचियों आदि तक सीमित नहीं कर सकता – dinkelk

+0

@babydanks आप यह पता लगा सकते हैं कि यह किसी भी फ़ंक्शन को कॉल करता है, जिसे इसे 'ओपन' की तरह नहीं करना चाहिए। – iabdalkader

+0

आह! यह किस स्तर पर करना आसान है? एक बार आपके पास एक अस्थिर कार्य नोड हो जाए? (यानी 'ओपन' की जांच करने का सबसे आसान तरीका क्या होगा?) – dinkelk