वैरिएबल को ब्लॉक के बाहर उपलब्ध स्टेटमेंट के साथ परिभाषित किया गया है?


90

निम्नलिखित उदाहरण पर विचार करें:

with open('a.txt') as f:
    pass
# Is f supposed to be defined here?

मैंने पीईपी -343 के साथ-साथ स्टेटमेंट के लिए भाषा डॉक्स (2.7) पढ़ा है, लेकिन जहां तक ​​मैं बता सकता हूं कि वे इस मामले पर कुछ नहीं कहते हैं।

CPython में 2.6.5 fको ब्लॉक के बाहर परिभाषित किया गया प्रतीत होता है, लेकिन मैं कार्यान्वयन विस्तार पर भरोसा नहीं करूंगा जो बदल सकता है।


8
संलग्नक के दायरे में उपलब्ध होगा या नहीं, इस सवाल का जवाब पहले ही दिया जा चुका है। मेरे लिए संदर्भ प्रबंधकों की संपूर्ण अवधारणा तब क्लिक की गई जब मुझे महसूस हुआ कि किसी संदर्भ की अवधारणा गुंजाइश से भिन्न है । यहाँ मेरी वेबसाइट का एक लिंक है जो उम्मीद करता है कि थोड़ी मदद करता है: markus-gattol.name/ws/python.html#context_manager
— टॉम

1
वास्तव में - एक संदर्भ वर्तमान स्थिति को बदलने का मामला है - फ़ाइल खुला, फ़ाइल बंद या थ्रेड लॉक / अनलॉक। उपकरण आवंटित / डीलॉलेट किया गया। दायरे में नामित सभी चर अभी भी हैं - लेकिन वे अब डीलॉलेटेड / बंद / अनलॉक किए गए हैंडल को इंगित करेंगे।
— डैनी स्टेपल

जवाबों:


159

हां, संदर्भ प्रबंधक विवरण के साथ उपलब्ध होगा और यह कार्यान्वयन या संस्करण पर निर्भर नहीं है। बयानों के साथ एक नया निष्पादन क्षेत्र नहीं बनता है।


3
यह मेरी राय में सबसे स्पष्ट स्पष्टीकरण है इसलिए स्वीकृत जवाब को प्रदान करना; अतिरिक्त उपयोगी जानकारी के लिए एलेक्स और TokenMacGuy को अंक देंगे।
— हिक्की टिवोनेन

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

28

withवाक्य रचना:

with foo as bar:
    baz()

इसके लिए लगभग चीनी है:

try:
    bar = foo.__enter__()
    baz()
finally:
    if foo.__exit__(*sys.exc_info()) and sys.exc_info():
        raise

यह अक्सर उपयोगी होता है। उदाहरण के लिए

import threading
with threading.Lock() as myLock:
    frob()

with myLock:
    frob_some_more()

संदर्भ प्रबंधक एक से अधिक बार उपयोग का हो सकता है।


ठीक है, लॉक का पुन: उपयोग हो सकता है या नहीं (कोई विचार नहीं है, लेकिन यह एक बग होगा यदि वे अलग-अलग थे) - लेकिन पायथन स्कूपिंग नियम निश्चित रूप से कार्यान्वयन के दौरान यहां समान होंगे।
— फजीमैन

1
यह फिर से एक मुद्दा नहीं है। स्कूपिंग समान होगी। हालाँकि, अगर foo .__ के कार्यान्वयन से बाहर निकलें__ थ्रेड को एक बंद स्थिति में डालते हैं, तो जब तक कि लॉक में एक एंटर नहीं होता है जो इसे फिर से खोल देता है, दूसरा स्टेटमेंट ऐसा नहीं लगता है कि यह थ्रेड लॉक के लिए कुछ भी उपयोगी होगा।
— डैनी स्टेपल

16

मामले fमें एक फाइल है, यह withबयान के बाहर बंद दिखाई देगा ।

उदाहरण के लिए, यह

f = 42
print f
with open('6432134.py') as f:
    print f
print f

प्रिंट होगा:

42
<open file '6432134.py', mode 'r' at 0x10050fb70>
<closed file '6432134.py', mode 'r' at 0x10050fb70>

आप अनुभाग विवरण के तहत PEP-0343 में विवरण पा सकते हैं : 'कथन के साथ' । पायथन स्कोप के नियम (जो परेशान कर सकते हैं ) भी लागू होते हैं f।


मुझे यह पता है, मैंने सवाल में इसका उल्लेख किया है। CPython के लिए 2.6.5 कम से कम। लेकिन क्या आप इस बात की गारंटी दे सकते हैं कि यह वही है जो ज्योन, आयरनपिथॉन और पायपी के लिए है?
— हीकी टिवोनेन

पायथन के स्कोप नियम हमेशा इतने स्पष्ट नहीं होते हैं। सीपीथॉन 2.6.5 में इस पर विचार करें [x for x in [1]]:। xउस के बाहर उपलब्ध है। इसे जनरेटर में बनाएँ (x for x in [1]):। अब xउपलब्ध नहीं है। मुझे याद है कि यह पायथन 3 में बदल गया है ताकि लिस्ट के साथ भी कॉम्प्रिहेंशन xलीक न हो, लेकिन मुझे अब संदर्भ नहीं मिल रहा है।
— हेइकी टिवोनेन

मैंने खोज की, लेकिन अभी के लिए कुछ भी महत्वपूर्ण नहीं पाया है। दिलचस्प सवाल है, हालांकि।
— मिकू

वास्तव में यह कोई स्कोप मामला नहीं है - वेरिएबल f अभी भी उपलब्ध है, लेकिन यह अब बंद अवस्था में फाइल करने के लिए हैंडल है - वही फाइल जो पहले खुली थी। जब संदर्भ छोड़ दिया जाता है तो निकास कॉल इस स्थिति को बदल देगा।
— डैनी स्टेपल

11

टिप्पणियों में हीकी के सवाल का जवाब देने के लिए: हाँ, यह डरावना व्यवहार अजगर भाषा विनिर्देश का हिस्सा है और किसी भी और सभी आज्ञाकारी पायथन (जिसमें PyPy, Jython, और IronPyonon शामिल हैं) पर काम करेगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.