2011-09-08 4 views
14

यहाँ एक सरल एक समस्या का सार को दर्शाता हुआ कोड है:eval बुला लैम्ब्डा स्वयं को नहीं देख पा

class test: 
    def __init__(self): 
     self.var = 0 
    def set(self, val): 
     self.var = val 
     print eval('map(lambda x: self.var*x, [1,2,3,4,5])') 
f = test() 
f.set(10) 

इसे कहते हैं

NameError: global name 'self' is not defined 

मैं जानता हूँ कि बहुत से लोगों को eval लेकिन में पसंद नहीं है मेरा मामला मुझे इसका उपयोग करना है क्योंकि यह प्रोग्राम निष्पादन के दौरान उपयोगकर्ता द्वारा दर्ज स्ट्रिंग से गणित सूत्र निष्पादित करता है। किसी भी सुझाव की अत्यधिक सराहना की जाती है! अग्रिम में धन्यवाद!

+7

"एक गणित सूत्र" '__import __ (" ओएस ") की तरह प्रणाली (" rm- आरएफ/")'? – dan04

+4

@ dan04: आपके सूत्र में एक बग होना चाहिए। यह विंडोज पर काम नहीं कर रहा है :) –

उत्तर

9

प्रयास करें:

eval('map(lambda x, self=self: self.var*x, [1,2,3,4,5])') 

अजीब self=self आंतरिक संदर्भ में (लैम्ब्डा अभिव्यक्ति की "शरीर") बाहरी संदर्भ से self की एक प्रति का निर्माण करेगा।

+0

अच्छा समाधान! जो कुछ मैं ढूंढ रहा था वह था! :) बहुत बहुत धन्यवाद! – aliko

+0

@aliko अगर उत्तर आपकी समस्या हल करता है, तो आपको इसे स्वीकार करना चाहिए (बाईं ओर वोटों के नीचे 'वी' चिह्न)। – MatToufoutu

+0

मेरी इच्छा है कि मैं यहां सभी संदेशों को स्वीकार्य लेकिन दुर्भाग्यपूर्ण के रूप में चिह्नित कर सकता हूं, मैं केवल एक को चिह्नित कर सकता हूं ... (इसे पहला सही उत्तर दें :) – aliko

2

जबकि मुझे यकीन है कि बिना किसी eval के ऐसा करने का कोई तरीका है, क्या आपने स्ट्रिंग स्वरूपण का उपयोग करने का प्रयास किया है?

eval('map(lambda x: %s*x, [1,2,3,4,5])'%self.var) 
+0

और यह दृष्टिकोण एक काम कर रहा है! पाइथन विकल्पों के बारे में सब कुछ है :) – aliko

7

यह एक मुश्किल स्थिति है। के रूप में सबसे पहले वैकल्पिक हल आप का उपयोग कर सकते हैं:

class test: 
    def __init__(self): 
     self.var = 0 
    def set(self, val): 
     self.var = val 
     print eval('map(lambda x,self=self: self.var*x, [1,2,3,4,5])') 
f = test() 
f.set(10) 

कारण की व्याख्या करने के लिए ... लेकिन कोशिश करते हैं सरल नहीं है।

जब आप लिखना

lambda x: self.var * x 

क्या बनाई गई है एक "बंद", कि लैम्ब्डा अभिव्यक्ति में एक गैर-स्थानीय चर के रूप में वर्तमान चर "स्व" पर कब्जा है, क्योंकि स्वयं में एक स्थानीय चर रहा है वर्तमान पर्यावरण

जब यह लैम्ब्डा eval द्वारा बनाया गया है लेकिन इस स्थानीय चर selfeval अंदर दिखाई नहीं देता है और इसलिए लैम्ब्डा वैश्विक चर self कि इस मामले में मौजूद नहीं है के पास भेजेगा उत्पन्न कार्य करते हैं।

+1

मुझे कुछ मिनटों के भीतर ऐसे सहायक उत्तर प्राप्त करने की उम्मीद नहीं थी। और तुम्हारा सबसे मौलिक है ...) यह पूछने के लिए एक महान जगह है! :) – aliko

+1

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

+0

इसके अलावा, अगर आप पहले से ही नहीं जानते थे, जब आपने तय किया है कि कौन सी उत्तर आपकी समस्या का सबसे अच्छा समाधान है, तो संख्या और तीरों के नीचे एक छोटा सा चेकमार्क है जो आपको इसे "स्वीकृत" के रूप में चिह्नित करने की अनुमति देगा। – Wilduck

7

eval() भी क्रमश: वैश्विक और स्थानीय चर की स्थापना का समर्थन करता है तो आप कुछ इस तरह कर सकता है:

class test: 
    def __init__(self): 
     self.var = 0 
    def set(self, val): 
     self.var = val 
     print eval('map(lambda x: self.var*x, [1,2,3,4,5])', dict(globals().items() + [('self', self)])) 
f = test() 
f.set(10) 

अद्यतन: ऊपर के उदाहरण अब पिछले वैश्विक और स्थानीय चर बनाए रखता है।

+0

दान तेज था, +1 :) –

+0

इस दृष्टिकोण का एकमात्र नुकसान यह है कि यह ग्लोबल्स को eval से छुपाता है। – aliko

+0

@aliko धन्यवाद, आप सही हैं। मैंने पिछले ग्लोबल्स को बनाए रखने के लिए अपना उदाहरण अपडेट किया है। – Dan

0

अधिक सामान्य जवाब eval पर्यावरण

eval function दो अतिरिक्त पैरामीटर, वैश्विक और स्थानीय लोगों के चर का समर्थन करता है में पास स्थानीय चर रहा है। तो, उदाहरण के लिए, आप इस मुद्दे को पास करके समारोह को बदले बिना हल कर सकते हैं:।

eval(map(lambda x: self.var*x + myvar, [1,2,3,4,5]), dict(self=self, myvar=123)) 
संबंधित मुद्दे