2012-11-30 24 views
5

अनुक्रम अनपॅकिंग अनुक्रम है? उदाहरण:अनुक्रम अनपॅकिंग अनुक्रम है?

(a, b) = (c, d) 

मैं इस धारणा के तहत हूं कि यह नहीं है।

संपादित करें: मेरा मतलब बहु-थ्रेडिंग के संदर्भ में परमाणु था, यानी कि पूरा कथन अविभाज्य है, क्योंकि परमाणुओं का उपयोग किया जाता था।

+1

मैं इस धारणा के तहत हूं कि आप आमतौर पर सॉफ़्टवेयर विकास में परमाणुता द्वारा * सामान्य रूप से समझने के द्वारा गलतफहमी कर रहे हैं। क्या आप यहां थ्रेड सुरक्षा के बारे में बात कर रहे हैं, या आप सोच रहे हैं कि 'बी = डी' से पहले' ए = सी 'निष्पादित किया जाएगा या नहीं? –

+0

@MartijnPieters - यदि ओपी बाद के बारे में सोच रहा था, तो ओपी बहुत उलझन में होगा क्यों '(ए, बी) = (बी, ए)' कुछ वैल्यू स्वैप करने के लिए काम करेगा। यह थ्रेड सुरक्षा के बारे में एक सवाल होना चाहिए। –

+0

@TedHopp: सवाल यह कहने के लिए बहुत अस्पष्ट है, और मेरे अनुभव में अनपॅकिंग में उलझन में बहुत भ्रम पैदा होता है। –

उत्तर

6

यह एक ऑपरेशन है; इससे पहले बाएं हाथ के काम लागू किया जाता है दाएँ हाथ अभिव्यक्ति मूल्यांकन किया जाता है:

>>> a, b = 10, 20 
>>> a, b 
(10, 20) 
>>> b, a = a, b 
>>> a, b 
(20, 10) 
>>> a, b = a*b, a/b 
>>> a, b 
(200, 2) 

या, यदि आप मल्टी-थ्रेडेड वातावरण के बारे में बात कर रहे हैं, तो काम है नहीं परमाणु; दुभाषिया एक भी opcode के साथ एक टपल काम का मूल्यांकन करता है, लेकिन अलग opcodes का उपयोग करता है तो प्रत्येक प्रभावित चर में परिणाम स्टोर करने के लिए: के लिए

>>> def t(self): a,b=20,20 
... 
>>> dis.dis(t) 
    1   0 LOAD_CONST    2 ((20, 20)) 
       3 UNPACK_SEQUENCE   2 
       6 STORE_FAST    1 (a) 
       9 STORE_FAST    2 (b) 
      12 LOAD_CONST    0 (None) 
      15 RETURN_VALUE   

हालांकि, सामान्य असाइनमेंट हमेशा कम से कम दो opcodes होने जा रहा है (एक दाईं ओर अभिव्यक्ति, परिणाम को संग्रहित करने के लिए एक), इसलिए सामान्य में सामान्य आकलन परमाणु नहीं है। अनुक्रम अनपॅकिंग कोई अलग नहीं है।

+1

मुझे लगता है कि यह 'परमाणु' अभिव्यक्ति नहीं है। यहां तक ​​कि 'j = i + 1' उच्च स्तर की भाषाओं में परमाणु नहीं है। मेरे पास अजगर में 'सेमफोर' है .... मैंने सवाल गलत समझा? –

+0

यह वास्तव में स्थापित नहीं करता है कि यह परमाणु है। सवाल यह है कि एक समवर्ती माहौल में 'ए' और' बी 'को उनके मूल्य परमाणु रूप से (यानि एक अविभाज्य ऑपरेशन के रूप में) असाइन किया गया है। मुझे विश्वास नहीं है कि वे हैं; यानी, यदि '(ए, बी)' को पिछले चरण में मूल्यों (200, 2) 'के साथ समाप्त करना है, तो दूसरा धागा' (200, 10) 'या' (20, 2) 'देख सकता है। –

+0

मैंने प्रश्न को गलत समझा (या इसके बजाय, मैंने टुपल एग्जिगमेंट्स के बारे में अधिक सामान्य प्रश्न के संदर्भ में बहुत ही कम प्रश्न का व्याख्या करने का विकल्प चुना)। मैंने इसे थ्रेड-सुरक्षा जानकारी शामिल करने के लिए अपडेट किया है। –

4

निश्चित रूप से एक मल्टी-थ्रेडेड वातावरण में परमाणु नहीं, निम्न स्क्रिप्ट का उपयोग कर परीक्षण किया:

import threading 

a, b = 10, 10 
finished = False 
def thr(): 
    global finished 
    while True: 
     # if sequence unpacking and assignment is atomic then (a, b) will always 
     # be either (10, 10) or (20, 20). Could also just check for a != b 
     if (a, b) in [(10, 20), (20, 10)]: 
      print('Not atomic') 
      finished = True 
      break 

t = threading.Thread(target=thr) 
t.start() 

while True: 
    for i in range(1000000): 
     a, b = 20, 20 
     a, b = 10, 10 
    if finished: 
     t.join() 
     break 

CPython 2.6, 2.7, और 3.2 का उपयोग कर परीक्षण किया गया। प्रत्येक संस्करण पर इस स्क्रिप्ट ने 'परमाणु नहीं' मुद्रित किया और एक सेकंड के नीचे अच्छी तरह से बाहर निकला।

+1

आपने मुझे ऑपकोड को दोबारा जांच लिया; अनपैक एक है, लेकिन फिर दो STORE_FAST ऑपकोड हैं, प्रत्येक प्रभावित चर के लिए एक। बीच में कुछ अलग करने के लिए एक और थ्रेड के अवसरों की संभावना है। –

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