__Del__ পদ্ধতিটি কী, কীভাবে এটি কল করবেন?


108

আমি একটি কোড পড়ছি। একটি শ্রেণি রয়েছে যেখানে __del__পদ্ধতিটি সংজ্ঞায়িত করা হয়। আমি বুঝতে পেরেছি যে এই পদ্ধতিটি ক্লাসের কোনও উদাহরণকে ধ্বংস করতে ব্যবহৃত হয়। তবে, আমি এই জায়গাটি ব্যবহার করার জায়গা খুঁজে পাচ্ছি না। যে জন্য প্রধান কারণ যে, আমি কিভাবে এই পদ্ধতি ব্যবহার করা হয় জানি না, সম্ভবত ভালো যে: obj1.del()। সুতরাং, আমার প্রশ্নগুলি __del__পদ্ধতিটি কল করবেন কীভাবে ?

উত্তর:


168

__del__একটি চূড়ান্তকরণকারী । যখন কোনও বস্তুটি আবর্জনা সংগ্রহ করা হয় তখন বলা হয় যা বস্তুর সমস্ত উল্লেখ মুছে ফেলার পরে এক পর্যায়ে ঘটে।

একটি সাধারণ ক্ষেত্রে এটি ঠিক বলার পরে del xবা xফাংশন শেষ হওয়ার পরে যদি স্থানীয় ভেরিয়েবল হয় right বিশেষত, বিজ্ঞপ্তি উল্লেখ না থাকলে সিপিথন (মানক পাইথন বাস্তবায়ন) অবিলম্বে আবর্জনা সংগ্রহ করবে।

তবে এটি সিপিথনের একটি বাস্তবায়ন বিশদ । পাইথন আবর্জনা সংগ্রহের একমাত্র প্রয়োজনীয় সম্পত্তি হ'ল এটি সমস্ত তথ্যসূত্র মুছার পরে ঘটে থাকে , সুতরাং এটি ঠিক পরে ঘটবে না এবং সম্ভবত ঘটবে না

আরও বেশি, ভেরিয়েবলগুলি বহু কারণে দীর্ঘকাল বেঁচে থাকতে পারে , উদাহরণস্বরূপ একটি প্রচারকারী ব্যতিক্রম বা মডিউল ইন্ট্রোস্পেকশন পরিবর্তনশীল রেফারেন্স গণনাটিকে ০ এর চেয়ে বেশি রাখতে পারে vari এছাড়াও, ভেরিয়েবল উল্লেখের চক্রের একটি অংশ হতে পারে - আবর্জনা সংগ্রহের সাথে সিপিথন বেশিরভাগ বিরতিতে পরিণত হয় , কিন্তু সমস্ত নয়, এই জাতীয় চক্র এবং তারপরেও কেবল সময়ে সময়ে।

এটি কার্যকর করার কোনও গ্যারান্টি নেই বলে আপনার যে কোডটি চালানো দরকার সেটিকে কখনই প্রবেশ করা উচিত নয়__del__() - পরিবর্তে, এই কোডটি এর finallyধারাটির অন্তর্গতtry ব্লকের বা কোনও withবিবৃতিতে একটি প্রসঙ্গ পরিচালকের অন্তর্ভুক্ত । যাইহোক, আছে বৈধ ব্যবহারের ক্ষেত্রে জন্য __del__: যেমন যদি একটি বস্তু Xরেফারেন্স Yএবং একটি কপি রাখে Yএকটি বিশ্বব্যাপী রেফারেন্স cache( cache['X -> Y'] = Yজন্য ভদ্র) তাহলে এটি হবে X.__del__এছাড়াও ক্যাশে এন্ট্রি মুছে দিন।

যদি তুমি জানো যে বিনাশকারী উপলব্ধ একটি প্রয়োজনীয় পরিষ্করণ (উপরে গাইডলাইন লঙ্ঘন), আপনি করতে চাইবেন এটা সরাসরি কল , যেহেতু নেই পদ্ধতি হিসেবে এটি সম্পর্কে বিশেষ কিছুই: x.__del__()। স্পষ্টতই, আপনি কেবল তখনই তা করা উচিত যদি আপনি জানেন যে এটির জন্য দুবার ডাকতে আপত্তি নেই। অথবা, সর্বশেষ অবলম্বন হিসাবে, আপনি এই পদ্ধতিটি ব্যবহার করে নতুন করে সংজ্ঞা দিতে পারেন

type(x).__del__ = my_safe_cleanup_method  

5
আপনি বলছেন যে কোনও বস্তুর রেফারেন্স গণনা শূন্যের সাথে সাথেই মুছে ফেলার সিপিথনের বৈশিষ্ট্য হ'ল "বাস্তবায়ন বিশদ"। আমি আস্থশীল হতে পারছি না. আপনি কি এই দাবির পিছনে কোনও লিঙ্ক সরবরাহ করতে পারেন? (আমি বোঝাতে চাইছি, গা font় ফন্টটি নিজেই বেশ
স্টুয়ার্ট বার্গ

14
সিপিথন বাস্তবায়ন বিশদ: সিপিথন বর্তমানে চক্রাকারে সংযুক্ত আবর্জনা সনাক্তকরণ (alচ্ছিক) সাথে একটি রেফারেন্স-কাউন্টিং স্কিম ব্যবহার করে, ... অন্যান্য বাস্তবায়ন আলাদাভাবে কাজ করে এবং সিপিথন পরিবর্তন হতে পারে। ( docs.python.org/2/references/datamodel.html )
এন।

সঙ্গে কী __exit__এই প্রেক্ষাপটে? এটি আগে __del__বা একসাথে চালানো হয়?
একাকী

1
প্রোগ্রামটি শেষ হয়ে গেলে কি "কিছুতেই না ঘটতে পারে" অন্তর্ভুক্ত?
অ্যান্ডি হেডেন

1
@ অ্যান্ডি হেডেন: __del__প্রোগ্রামগুলি সমাপ্তির সময় এমনকি পদ্ধতিগুলি চলতে পারে না এবং এমনকি তারা সমাপ্তির সময়ও চালিত হয়, __del__এমন একটি পদ্ধতি লিখতে হয় যা ডায়ালটার আপনার চারপাশে স্ব-বিকাশে ব্যস্ত থাকা সত্ত্বেও সঠিকভাবে কাজ করে তবে অনেক প্রোগ্রামার প্রয়োগ করার চেয়ে আরও সতর্ক কোডিং প্রয়োজন। (সিপিথন ক্লিনআপ সাধারণত __del__দোভাষী শটডাউনে চালনার পদ্ধতি পায় , তবে এখনও এটি পর্যাপ্ত নয় এমন কেস রয়েছে Da ডেমন থ্রেডস, সি-লেভেল গ্লোবালগুলি __del__এবং অন্যের সাথে তৈরি সামগ্রীর ফলে __del__সমস্ত __del__পদ্ধতি চলমান পথে পরিচালিত হতে পারে ))
ব্যবহারকারী 2357112 সমর্থন করে মনিকা

80

আমি অন্য প্রশ্নের উত্তর লিখেছিলাম, যদিও এটি এটির জন্য আরও সঠিক প্রশ্ন।

কনস্ট্রাক্টর এবং ডেস্ট্রাক্টররা কীভাবে কাজ করে?

এখানে একটি সামান্য মতামত উত্তর দেওয়া হয়।

ব্যবহার করবেন না __del__। এটি সি ++ বা ধ্বংসকারীদের জন্য নির্মিত ভাষা নয়। __del__পদ্ধতি সত্যিই, পাইথন 3.x মধ্যে সর্বস্বান্ত করা উচিত, যদিও আমি নিশ্চিত কেউ একটি ব্যবহারের ক্ষেত্রে যে অর্থে তোলে পাবেন আছি। আপনার যদি প্রয়োজন হয় __del__তবে http://docs.python.org/references/datamodel.html প্রতি প্রাথমিক সীমাবদ্ধতা সম্পর্কে সচেতন হন :

  • __del__যখন আবর্জনা সংগ্রহকারী বস্তুগুলি সংগ্রহ করার ঘটনা ঘটে তখন আপনাকে বলা হয়, যখন আপনি কোনও অবজেক্টের শেষ রেফারেন্সটি হারিয়ে ফেলেন এবং যখন আপনি নির্বাহ করেন তখন নয় del object
  • __del__ যে কোনও কল করার জন্য দায়ী __del__ সুপারক্লাসে যেকোনকে , যদিও এটি পদ্ধতি সমাধানের আদেশে (এমআরও) বা প্রতিটি সুপারক্লাসকে কল করার ক্ষেত্রে এটি স্পষ্ট নয়।
  • __del__আবর্জনা সংগ্রহকারী যে কোনও চক্রযুক্ত লিঙ্কগুলি সনাক্ত এবং পরিষ্কার করা থেকে বিরত থাকার একটি উপায় রাখে যেমন কোনও লিঙ্কযুক্ত তালিকার শেষ উল্লেখটি হারাতে। আপনি gc.garbage থেকে অবহেলিত সামগ্রীর একটি তালিকা পেতে পারেন। পুরোপুরি চক্র এড়াতে আপনি কখনও কখনও দুর্বল উল্লেখগুলি ব্যবহার করতে পারেন। এটি এখন এবং তারপরে বিতর্কিত হয়: দেখুন http://mail.python.org/pipermail/python-ideas/2009- অক্টোবর/006194 . html দেখুন
  • দ্য __del__ফাংশন প্রতারণা করতে পারেন, একটি অবজেক্ট একটি রেফারেন্স সংরক্ষণ, এবং আবর্জনা সংগ্রহ বাঁধন।
  • ব্যতিক্রম স্পষ্টভাবে উত্থাপিত __del__ এড়ানো হবে।
  • __del__পরিপূরক __new__অনেক বেশি __init__। এটি বিভ্রান্তিকর হয়। দেখুন http://www.algorithm.co.il/blogs/programming/python-gotchas-1- del -is-not-the- বিপরীতে-অফ- আরম্ভ / একটি ব্যাখ্যা এবং gotchas জন্য।
  • __del__পাইথনের কোনও "ভাল-প্রিয়" শিশু নয়। আপনি লক্ষ্য করবেন যে sys.exit () ডকুমেন্টেশন সুনির্দিষ্টভাবে প্রস্থান করার আগে আবর্জনা সংগ্রহ করা হয়েছে কিনা তা নির্দিষ্ট করে না এবং প্রচুর বিজোড় সমস্যা রয়েছে। __del__গ্লোবালগুলিতে কল করার ফলে বিজোড় অর্ডিং সমস্যার কারণ হয়, যেমন: http://bugs.python.org/issue5099 । করা উচিত __del__নামক এমনকি যদি __init__ব্যর্থ হয়? দীর্ঘ থ্রেডের জন্য দেখুন http://mail.python.org/pipermail/python-dev/2000-Mark/thread.html#2423

কিন্তু অন্য দিকে:

  • __del__এর অর্থ আপনি একটি নিকটবর্তী বিবৃতি কল করতে ভুলবেন না। প্রো প্রো দৃষ্টিভঙ্গির জন্য http://eli.thegreenplace.net/2009/06/12/safely- using-destructors-in-python/ দেখুন __del__। এটি সাধারণত সিটিপস বা অন্য কোনও বিশেষ সংস্থান মুক্ত করার বিষয়ে।

এবং __del__ফাংশনটি পছন্দ না করার জন্য আমার ব্যর্থ কারণ ।

  • যখনই কেউ __del__এটিকে নিয়ে আসে তখন বিভ্রান্তির ত্রিশ বার্তায় পরিণত হয়।
  • পাইথনের জেনে এটি এই আইটেমগুলিকে ভেঙে দেয়:
    • সহজ জটিল চেয়ে ভাল।
    • বিশেষ কেসগুলি নিয়ম ভাঙার পক্ষে যথেষ্ট বিশেষ নয়।
    • ত্রুটিগুলি কখনই নিঃশব্দে কাটানো উচিত নয়।
    • অস্পষ্টতার মুখে অনুমান করার প্রলোভনটি অস্বীকার করুন।
    • এটির জন্য সুস্পষ্ট উপায় - এবং কেবলমাত্র একটিই - সেখানে থাকতে হবে।
    • যদি বাস্তবায়নটি ব্যাখ্যা করা শক্ত হয় তবে এটি একটি খারাপ ধারণা।

সুতরাং, ব্যবহার না করার কারণ খুঁজে নিন __del__


6
এমনকি যদি প্রশ্নটি ঠিক না হয়: আমরা কেন ব্যবহার করব না __del__, তবে কীভাবে কল করব __del__, আপনার উত্তর আকর্ষণীয়।
nbro

ধন্যবাদ। কখনও কখনও সেরা ধারণাটি হ'ল ভয়ঙ্কর ধারণা থেকে দূরে সরে যায়।
চার্লস মেরিয়ামিয়াম

অন্যান্য খবরে, আমি উল্লেখ করতে ভুলে গেছি যে পাইপাই (দীর্ঘকালীন চলমান অ্যাপ্লিকেশনগুলির জন্য একটি দ্রুত দোভাষী) ডেল ভাঙ্গবে ।
চার্লস মেরিয়ামিয়াম

ভাঙ্গা লিঙ্কটি আপডেট করার জন্য @ গ্লোইনকে ধন্যবাদ!
চার্লস মেরিয়ামিয়াম

@CharlesMerriam ধন্যবাদ আপনি উত্তরের জন্য!
টম বুড়ো

13

__del__পদ্ধতি, এটা যখন বস্তুর আবর্জনা সংগ্রহ করা হয় ডাকা হবে। মনে রাখবেন এটি অবশ্য বলা হওয়ার নিশ্চয়তা দেয় না। নিম্নলিখিত কোড নিজে থেকে এটি অগত্যা করবে না:

del obj

কারণটি হ'ল কেবল একটি delকরে রেফারেন্স গণনা হ্রাস করে। যদি অন্য কোনও জিনিসের সাথে রেফারেন্স থাকে তবে__del__ হবে না।

__del__যদিও ব্যবহার করার জন্য কয়েকটি সতর্কতা রয়েছে । সাধারণত, এগুলি সাধারণত খুব কার্যকর হয় না। আপনি আরও ঘনিষ্ঠ পদ্ধতি বা বিবৃতি সহ একটি সম্ভবত ব্যবহার করতে চান এমনটি আমার কাছে আরও শোনাচ্ছে ।

পদ্ধতিগুলিতে পাইথন ডকুমেন্টেশন__del__ দেখুন ।

অন্য একটি বিষয় লক্ষণীয়: __del__পদ্ধতিগুলি অতিরিক্ত ব্যবহার করা না হলে আবর্জনা সংগ্রহকে বাধা দিতে পারে। বিশেষত, একটি বৃত্তাকার রেফারেন্স যাতে কোনও __del__পদ্ধতির সাথে একাধিক অবজেক্ট থাকে তা আবর্জনা সংগ্রহ করবে না। এটি কারণ আবর্জনা সংগ্রহকারী জানেন না যে প্রথমে কোনটিকে কল করা উচিত। আরও তথ্যের জন্য জিসি মডিউলে ডকুমেন্টেশন দেখুন ।


8

__del__যখন আপনার বস্তুর পরিশেষে ধ্বংস করা হয় পদ্ধতি (নোট বানান!) বলা হয়। প্রযুক্তিগতভাবে বলতে গেলে (সিপিথনে) এটি তখন যখন আপনার অবজেক্টের কোনও রেফারেন্স থাকে না, অর্থাৎ যখন এটি সুযোগের বাইরে চলে যায়।

আপনি যদি নিজের অবজেক্টটি মুছতে চান এবং এভাবে __del__পদ্ধতিটি কল করুন

del obj1

যা বস্তুটি মুছে ফেলবে (প্রদত্ত যে এটিতে অন্য কোনও উল্লেখ ছিল না)।

আমি আপনাকে এইভাবে একটি ছোট ক্লাস লেখার পরামর্শ দিচ্ছি

class T:
    def __del__(self):
        print "deleted"

এবং পাইথন ইন্টারপ্রেটারে তদন্ত করুন, যেমন

>>> a = T()
>>> del a
deleted
>>> a = T()
>>> b = a
>>> del b
>>> del a
deleted
>>> def fn():
...     a = T()
...     print "exiting fn"
...
>>> fn()
exiting fn
deleted
>>>   

নোট করুন যে জেথন এবং আয়রনপাইথনের বিভিন্ন নিয়ম রয়েছে ঠিক কখন অবজেক্টটি মুছে ফেলা হয় এবং __del__ডাকা হয়। এটি ব্যবহার করা ভাল অনুশীলন হিসাবে বিবেচিত হয় না __del__যদিও এটির কারণে এবং বস্তু এবং তার পরিবেশটি যখন ডাকা হয় তখন এটি অজানা অবস্থায় থাকতে পারে। একেবারে গ্যারান্টিযুক্ত নয় তবে __del__তা বলা হবে - দোভাষী সমস্ত বিষয় মুছে না ফেলে বিভিন্ন উপায়ে প্রস্থান করতে পারেন।


1
স্ট্যাকওভারফ্লো. com / use del obj1a/ 2452895/ 611007 এবং স্ট্যাকওভারফ্লো.com / a/ 1481512 / 611007 এর সাথে তুলনা করা , নির্ভর করা খারাপ ধারণা বলে মনে হচ্ছে।
n611x007

0

পূর্বে উল্লিখিত হিসাবে, __del__কার্যকারিতা কিছুটা বিশ্বাসযোগ্য নয়। এটি কার্যকর হতে পারে এমন ক্ষেত্রে, পরিবর্তে পদ্ধতি __enter__এবং __exit__পদ্ধতিগুলি ব্যবহারের বিষয়ে বিবেচনা করুন। এটি with open() as f: passফাইল অ্যাক্সেসের জন্য ব্যবহৃত সিনট্যাক্সের অনুরূপ আচরণ দেবে । __enter__এর স্কোপ এ প্রবেশ করার withসময় __exit__স্বয়ংক্রিয়ভাবে ডাকা হয়, যখন বাইরে বেরোনোর ​​পরে এটি স্বয়ংক্রিয়ভাবে কল হয়। আরও তথ্যের জন্য এই প্রশ্নটি দেখুন ।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.