2012-08-07 14 views
7

मैं हाल ही में पाइथन जेनरेटर के साथ प्रयोग कर रहा हूं, और मैं निम्नलिखित उत्सुक व्यवहार में आया हूं, और मुझे यह समझने में उत्सुकता है कि ऐसा क्यों होता है और क्या हो रहा है:पायथन - उत्सुक/अप्रत्याशित व्यवहार - ऑपरेटरों की प्राथमिकता

def generating_test(n): 
    for a in range(n): 
     yield "a squared is %s" % a*a # Notice instead of a**2 we have written a*a 

for asquare in generating_test(3): 
    print asquare 

आउटपुट:

a squared is 1 
a squared is 2a squared is 2 

निम्न स्क्रिप्ट जो अपेक्षित आउटपुट उत्पन्न बनाम:

def generating_test(n): 
    for a in range(n): 
     yield "a squared is %s" % a**2 # we use the correct a**2 here 

for asquare in generating_test(3): 
    print asquare 

आउटपुट:

a squared is 0 
a squared is 1 
a squared is 4 
+1

एक तरफ: यदि आप वास्तव में एक पूर्णांक स्वरूपित कर रहे हैं, तो '% d' का उपयोग करें,'% s' नहीं। – kojiro

+5

या नए 'प्रारूप' वाक्यविन्यास को गले लगाओ। मैंने सोचा कि यह थोड़ा लंबा था जब मैंने इसे पहली बार देखा लेकिन मुझे यह पसंद आया। – DSM

+0

एक सहकर्मी ने मुझे एक बार बताया, * हमेशा * '%' – chepner

उत्तर

20

इस जनरेटर से कोई लेना देना नहीं है:

>>> a = 2 
>>> "a squared is %s" % a 
'a squared is 2' 
>>> ("a squared is %s" % a)*a 
'a squared is 2a squared is 2' 
>>> "a squared is %s" % a*a 
'a squared is 2a squared is 2' 
>>> "a squared is %s" % (a*a) 
'a squared is 4' 

% सेशन स्ट्रिंग और पहली a तर्क के रूप में उपयोग, गुणा से पहले किया जाता है। आपका a**2 काम करता है क्योंकि **a और 2 के साथ ऑप के रूप में % से पहले मूल्यांकन किया जाता है।

+0

वह जल्दी था! – jamylak

+2

ये मुझे इसे हराया ... मुश्किल से: पी –

+0

बहुत रोचक, त्वरित प्रतिक्रिया के लिए धन्यवाद - मुझे अभी भी स्वीकार्य के रूप में चिह्नित करने के 11 मिनट पहले इंतजार करना होगा। मैंने जेनरेटर और उपज के लिए टैग हटा दिए हैं क्योंकि वे प्रासंगिक नहीं हैं। –

8

Python's order of operations पेम्डास लागू होने के बावजूद बाएं से दाएं से है। स्ट्रिंग प्रक्षेप ऑपरेटर जाहिरा तौर पर, क्योंकि यदि आप क्रम को उल्टा, गुणन प्रक्षेप के बाएँ बनाने, सापेक्ष और गुणा के रूप में ही पूर्वता है, यह पूर्वता लेता है:

>>> print 3 * "a foo %s" % 'hi' 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: not enough arguments for format string 
>>> print 3 * "a foo %s" % ('hi', 'ho', 'yo') 
a foo hia foo hoa foo yo 

लेकिन, जैसा कि आप का प्रदर्शन किया है, घातांक तुरुप बाएं से दाएं क्रम।

अद्यतन:

...% ऑपरेटर भी को स्ट्रिंग और यूनिकोड वस्तुओं से ओवरलोड हो गया है स्ट्रिंग स्वरूपण (भी प्रक्षेप के रूप में जाना जाता है) करते हैं: कि same document under Binary Arithmetic Operations में यह कुछ denotatively स्पष्ट है, लेकिन connotatively प्रासंगिक कहा गया है।

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

+2

उस दस्तावेज़ के अंत में सारांश इसे अधिक स्पष्ट रूप से रखता है - विशेष रूप से, फुटनोट 8 कहता है: "'% 'ऑपरेटर स्ट्रिंग स्वरूपण के लिए भी उपयोग किया जाता है; वही प्राथमिकता लागू होती है"। – lvc

+0

कल्पना कीजिए कि यह अन्यथा था ... आप पाइथन कोड को पार्स करने में सक्षम नहीं होंगे जब तक कि आप subexpressions के रनटाइम प्रकारों को नहीं जानते! – Aaron

+0

@Aaron * चीजें इतनी अलग होंगी कि वे नहीं हैं। * - [अन्ना रसेल] (http://en.wikipedia.org/wiki/Anna_Russell)। यदि प्रकार [एनोटेशन] (http://www.python.org/dev/peps/pep-3107/) को पायथन द्वारा आवश्यक था और संकलन समय पर प्रकार को लागू करने के लिए उपयोग किया जाता था, तो यह एक अलग भाषा होगी, लेकिन एक पागल विचार नहीं । :) – kojiro

5

जब आप अप्रत्याशित व्यवहार देखते हैं, तो इसे अपने सबसे सरल संभावित मामले में वितरित करके अपना विश्लेषण शुरू करें। एक साधारण मामला अध्ययन और समझना आसान होगा।

अनपेक्षित व्यवहार:

>>> 'hello %s' % 3 * 2 
'hello 3hello 3' 

(आप की उम्मीद 'hello 6')


हम कारण अजगर 'hello 3' * 2 बजाय 'hello %d' % 6 के रूप में आदेश की व्याख्या की जानी चाहिए।हम ब्रैकेट

>>> "hello %s" % (3*2) 
'hello 6' 

यूरेका के साथ दूसरी व्याख्या को मजबूर करने का प्रयास करें!

हमने दिखाया है कि स्ट्रिंग स्वरूपण ऑपरेटर % गुणा से अधिक या बराबर प्राथमिकता है। - हम अजगर प्रलेखन जाँच हाँ यह इस बात की पुष्टि इस http://docs.python.org/reference/expressions.html#summary

कि पूर्वता बराबर है इस बात की पुष्टि करने के लिए, हम इसे दूसरी तरह के आसपास की कोशिश कर सकते हैं: यह देखते हुए कि अल्पविराम (,) दोहराया गया है

>>> "%d,"*2%(1,2) 
'1,2,' 

, हम कारण "%d," * 2 स्ट्रिंग स्वरूपण % से पहले गुणा किया गया था। यदि गुणा स्ट्रिंग स्वरूपण से पहले हो सकता है, और स्ट्रिंग स्वरूपण गुणा से पहले हो सकता है, तो वे प्राथमिकता के बराबर होना चाहिए।

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