Account().observers
AccountObserver()
उदाहरणों को संदर्भित एक सेट है, लेकिन AccountObserver().theaccount
एक संदर्भ वापसAccount()
उदाहरण जहां पर्यवेक्षक सेट में संग्रहीत किया जाता है की ओर इशारा करते है। यह एक परिपत्र संदर्भ है।
आम तौर पर, कचरा कलेक्टर ऐसी मंडलियों का पता लगाएगा और चक्र तोड़ देगा, जिससे संदर्भ संख्या 0 तक गिर जाएगी और सामान्य सफाई हो जाएगी। हालांकि, एक अपवाद है, जो कक्षाओं के लिए __del__
विधि को परिभाषित करता है, क्योंकि डेविड के उदाहरण में कक्षाएं होती हैं। Python 2 gc
module documenation से:
gc.garbage
वस्तुओं जो कलेक्टर नहीं पहुंचा जा सकता हो पाया लेकिन मुक्त नहीं किया जा सकता है (uncollectable वस्तुओं) की सूची। डिफ़ॉल्ट रूप से, इस सूची में केवल __del__()
विधियों वाली वस्तुएं होती हैं। ऑब्जेक्ट्स जिनमें __del__()
विधियां हैं और संदर्भ चक्र का हिस्सा हैं, पूरे संदर्भ चक्र को अस्थिर करने योग्य, जिसमें ऑब्जेक्ट्स शामिल नहीं हैं, केवल चक्र में आवश्यक है लेकिन केवल इससे ही पहुंच योग्य है। पाइथन स्वचालित रूप से ऐसे चक्र एकत्र नहीं करता है, सामान्य रूप से, पाइथन के लिए सुरक्षित आदेश अनुमान लगाना संभव नहीं है जिसमें __del__()
विधियों को चलाने के लिए।
तो चक्र क्योंकि कचरा कलेक्टर अनुमान लगाना क्या finaliser (__del__
विधि) पहले कॉल करने के लिए मना कर दिया तोड़ा नहीं जा सकता है। ध्यान दें कि यादृच्छिक रूप से एक को चुनना विशिष्ट उदाहरण के लिए सुरक्षित नहीं है; यदि आप पहले Account().__del__
पर कॉल करते हैं, तो observers
सेट हटा दिया गया है और AccountObserver().__del__
पर आने वाली कॉल AttributeError
के साथ विफल हो जाएंगी।
एक कमजोर संदर्भ संदर्भ गणना में भाग नहीं लेता है; इसलिए यदि AccountObserver().theaccount
इसी Account()
बजाय उदाहरण के लिए बात करने के लिए एक कमजोर संदर्भ में प्रयोग किया जाता है, तो Account()
उदाहरण नहीं जिंदा रखा जाएगा अगर केवल कमजोर संदर्भ छोड़ दिया गया:
class AccountObserver(object):
def __init__(self, theaccount):
self.theaccountref = weakref.ref(theaccount)
theaccount.register(self)
def __del__(self):
theaccount = self.theaccountref()
if theaccount is not None:
theaccount.unregister(self)
def update(self):
theaccount = self.theaccountref()
print("Balance is %0.2f" % theaccount.balance)
def close(self):
print("Account no longer in use")
ध्यान दें कि मैं अजगर 2 प्रलेखन से लिंक। अजगर 3.4 के रूप में, यह नहीं रह गया है सच और उदाहरण में शो के रूप में भी परिपत्र निर्भरता साफ हो जाएगा, के रूप में PEP 442 – Safe object finalization लागू किया गया है:
प्राथमिक जैसे इस पीईपी संबंध finalizers साथ वस्तुओं के लाभ, अंततः ब्लॉक के साथ __del__
विधि और जनरेटर वाले ऑब्जेक्ट्स। जब वे संदर्भ चक्र का हिस्सा होते हैं तो उन वस्तुओं को पुनः दावा किया जा सकता है।
ऐसा नहीं है कि इससे ट्रेसबैक नहीं होगा; ट्रैस बैक सिर्फ एक चेतावनी अन्यथा है
>>> import gc
>>> del a, a_ob
>>> gc.collect()
Account no longer in use
Exception ignored in: <bound method AccountObserver.__del__ of <__main__.AccountObserver object at 0x10e36a898>>
Traceback (most recent call last):
File "<stdin>", line 6, in __del__
File "<stdin>", line 13, in unregister
AttributeError: 'Account' object has no attribute 'observers'
65
: यदि आप अजगर 3.6 में उदाहरण पर अमल, संदर्भ हटा देते हैं और शुरू एक कचरा संग्रहण रन, आप के रूप में Account().observers
सेट हटा दिया गया है की संभावना है ट्रैसबैक मिल , gc.collect()
कॉल सफल हुआ और ज़ोंबी AccountObserver()
और Account()
ऑब्जेक्ट्स का वैसे भी उपयोग किया जाता है।
उत्तर के लिए धन्यवाद, मार्टिजन। मेरे पास एक प्रश्न है- '__init __() 'के अंदर संशोधित' खाता ऑब्सर्वर 'कक्षा में, क्या यह गलत होगा अगर मैंने' रजिस्टर() 'को कमजोर के रूप में' theaccountref.register (self) 'के रूप में मूल' अकाउंट' रजिस्ट्रार (स्वयं) '? '__del __()' –
@Sajeev राजपूत के लिए भी जाता है: आपको 'theaccountref() रजिस्टर (स्वयं)' का उपयोग करना होगा, इसलिए * ऑब्जेक्ट * मूल ऑब्जेक्ट प्राप्त करने के संदर्भ में। लेकिन आपके पास पहले से ही उस ऑब्जेक्ट का संदर्भ है, स्थानीय चर 'अकाउंट' के रूप में, तो इसका उपयोग क्यों न करें? जब '__init__' समाप्त होता है, तो उस संदर्भ को हटाकर' theaccount' स्थानीय चर साफ़ कर दिया जाता है। –
@ सजीव राजपूत: '__del__' में आपके पास 'खाता()' उदाहरण के लिए कोई अन्य संदर्भ नहीं है; यह एक कमजोर संदर्भ का उपयोग करने का पूरा बिंदु है। तो आपको कमजोर वस्तु को कॉल करना होगा, और यदि 'कोई नहीं' वापस लौटाया गया था तो मूल वस्तु अब और नहीं है। –