2012-09-14 13 views
5

से अधिक के प्रलेखन अजगर 3.2 पुनरावृत्ति के weakref मॉड्यूल के WeakKeyDictionary और WeakValueDictionary इन कंटेनरों से अधिक पुनरावृत्ति पर एक नोट है:सुरक्षित रूप से WeakKeyDictionary और WeakValueDictionary

नोट: सावधानी: क्योंकि एक WeakKeyDictionary पर बनाया गया है एक पायथन शब्दकोश के शीर्ष पर, इसे आकार देने पर आकार को बदलना नहीं चाहिए। WeakKeyDictionary के लिए यह सुनिश्चित करना मुश्किल हो सकता है क्योंकि पुनरावृत्ति के दौरान कार्यक्रम द्वारा किए गए कार्यों से शब्दकोष में "जादू द्वारा" गायब हो सकता है (कचरा संग्रह के दुष्प्रभाव के रूप में)।

यह इन कंटेनर के व्यवहार के विनिर्देश के रूप में अपेक्षाकृत गंभीर लगता है। विशेष रूप से जब कोड चलाते हैं जो सीपीथॉन के कचरा कलेक्टर (चक्र युक्त डेटा संरचनाओं का उपयोग करते समय) या अन्य पायथन कार्यान्वयन (जैसे ज्योथन) का उपयोग करते हैं, तो ऐसा लगता है कि इन संग्रहों पर पुन: प्रयास करने का कोई सुरक्षित तरीका नहीं है।

कचरा कलेक्टर मेरे कार्यक्रम में किसी भी समय संदर्भ को साफ़ कर सकता है जब मैं इन संग्रहों पर सुरक्षित रूप से पुन: सक्रिय कैसे हो सकता हूं? सीपीथन के लिए समाधान होने से मेरी प्राथमिकता है लेकिन मुझे अन्य कार्यान्वयन पर भी इस मुद्दे के बारे में दिलचस्पी है।

क्या यह शायद एक कमजोर तरीका है जो WeakKeyDictionary पर फिर से शुरू हो सकता है?

import weakref 

d = weakref.WeakKeyDictionary() 

... 

for k, v in list(d.items()): 
    ... 

उत्तर

6

सुरक्षित होने के लिए आपको कहीं संदर्भ रखना होगा। मुहावरा का उपयोग करना:

for k,v in list(d.items()): 

पूरी तरह से सुरक्षित है, क्योंकि भले ही यह, समय के सबसे अधिक काम करेंगे पाश सूची कचरा-एकत्र हो सकता है की अंतिम यात्रा के दौरान नहीं है।

सही तरीका होगा:

items = list(d.items()) 
for k,v in items: 
    #do stuff that doesn't have a chance of destroying "items" 
del items 

आप एक WeakKeyDictionary का उपयोग करते हैं तो आप बस कुंजी संग्रहीत कर सकती है, और स्टोर मूल्यों अगर आप WeakValueDictionary का उपयोग करें।

एक तरफ ध्यान दें: python2 .items() में पहले से ही एक सूची लौटाती है।

आखिरकार यह "सुरक्षित" से आपका क्या मतलब है इस पर निर्भर करता है। क्योंकि शब्दकोश से अधिक यात्रा वास्तव में list(d.items()) द्वारा किया जाता है

for k,v in list(d.items()): 

सुरक्षित है,, तो आप केवल अधिक पुनरावृत्ति कर रहे हैं: आप बस मतलब अगर वह यात्रा सही ढंग से आगे बढ़ना होगा (सभी तत्वों पर एक बार पुनरावृत्ति), तो सूची।

यदि आप, इसके बजाय, इसका अर्थ यह है कि पुनरावृत्ति तत्वों के दौरान for -loop के दुष्प्रभाव के रूप में शब्दकोश से "गायब" नहीं होना चाहिए, तो आपको लूप के अंत तक एक मजबूत संदर्भ रखना चाहिए, और इसके लिए आवश्यक है लूप शुरू करने से पहले आप एक चर में सूची को स्टोर करने के लिए।

+2

आपका पहला उदाहरण असुरक्षित क्यों होगा? सूची में प्रत्येक कुंजी और मूल्य के लिए मजबूत संदर्भ होंगे और अंतिम पुनरावृत्ति के दौरान, 'के' और' v 'में रुचि रखने वाली वस्तुओं के लिए मजबूत संदर्भ होंगे। इसलिए अंतिम पुनरावृत्ति समाप्त होने से पहले सूची कचरा भी हो सकती है। क्या वह सही है? – Feuermurmel

+0

यह कहने जैसा है कि 'के लिए, v। Ditems() में सुरक्षित है, क्योंकि' k' और 'v' ऑब्जेक्ट्स के लिए मजबूत संदर्भ रखते हैं।अगर लूप के अंदर, 'k' और 'v' को हटाया जा सकता है, तो पुनरावृत्ति असुरक्षित है। 'WeakKeyDictionary' पर फिर से चलने वाले सरल कार्यों के लिए सुरक्षित होना चाहिए। – Bakuriu

+3

मैं शायद कुछ गलत समझ रहा हूं, लेकिन ऑब्जेक्ट्स 'के' और' v' संदर्भ कैसे हटाया जा सकता है? जब तक ये चर गुंजाइश में हैं और अधिक नहीं हैं, संदर्भित वस्तुएं सुरक्षित हैं। या क्या आप अंतिम पुनरावृत्ति के दौरान उन वस्तुओं के सभी मजबूत संदर्भों को हटाने के बारे में बात कर रहे हैं? इससे शब्दकोश बदल जाएगा लेकिन असुरक्षित नहीं होगा क्योंकि पुनरावृत्ति शुरू होने के बाद शब्दकोश का उपयोग नहीं किया जाता है। क्या आप अंतिम पुनरावृत्ति के दौरान क्या गलत हो सकते हैं इसका एक उदाहरण दे सकते हैं? – Feuermurmel

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