__Init __ () পিতামাত্ত শ্রেণীর __init __ () কল করা উচিত?


132

আমি অবজেক্টিভ-সি-তে এই নির্মাণটি ব্যবহার করেছি:

- (void)init {
    if (self = [super init]) {
        // init class
    }
    return self;
}

পাইথনও কি অভিভাবক শ্রেণির প্রয়োগের জন্য ডাকতে পারে __init__?

class NewClass(SomeOtherClass):
    def __init__(self):
        SomeOtherClass.__init__(self)
        # init class

এটি কি সত্য / মিথ্যা __new__()এবং এর জন্যও __del__()?

সম্পাদনা করুন: খুব অনুরূপ একটি প্রশ্ন রয়েছে: পাইথনে উত্তরাধিকার এবং ওভাররাইডিং__init__


আপনি আপনার কোড উল্লেখযোগ্যভাবে পরিবর্তন করেছেন। আমি বুঝতে পারি যে মূলটি objectটাইপো ছিল। তবে এখন আপনার superকাছে আপনার প্রশ্নের শিরোনামও নেই।
সাইলেন্টগোস্ট

আমি কেবল ভেবেছিলাম যে সুপারটি প্যারেন্ট ক্লাসের নাম হিসাবে ব্যবহৃত হয়। আমি ভাবিনি যে কেউ এই অনুষ্ঠানটি সম্পর্কে ভাববে। আমি কোনও ভুল বোঝাবুঝির জন্য দুঃখিত।
জর্জি স্কলি 14

একজন কেন স্বয়ংক্রিয় না সুপার কল প্রশ্ন: stackoverflow.com/questions/3782827/...
সিরো Santilli郝海东冠状病六四事件法轮功

উত্তর:


67

পাইথনে, সুপার-ক্লাসকে কল করা al __init__চ্ছিক। আপনি যদি এটি কল করেন তবে এটি superসনাক্তকারী ব্যবহার করবেন কিনা বা স্পষ্ট করে সুপার শ্রেণীর নামকরণ করা হবে কিনা তাও alচ্ছিক:

object.__init__(self)

বস্তুর ক্ষেত্রে, সুপার পদ্ধতিটি খালি থাকার কারণে সুপার পদ্ধতিটি কল করা কঠোরভাবে প্রয়োজন হয় না। একই জন্য __del__

অন্যদিকে, কারণ __new__, আপনাকে অবশ্যই সুপার পদ্ধতিটি কল করা উচিত, এবং এর রিটার্নটিকে সদ্য নির্মিত বস্তু হিসাবে ব্যবহার করা উচিত - যদি না আপনি স্পষ্টভাবে আলাদাভাবে কোনও কিছু ফিরিয়ে দিতে চান।


সুতরাং কোন সুপার এর বাস্তবায়ন কল করার জন্য কোন সম্মেলন আছে?
জর্জি স্কলি 14

5
পুরাতন স্টাইলের ক্লাসগুলিতে, সুপার ক্লাসে যদি একটি ডিআইএন সংজ্ঞায়িত করা থাকে (তবে এটি প্রায়শই হয় না) তবে আপনি কেবল সুপার আরম্ভ করতে পারেন । অতএব, লোকে সাধারণত নীতিটি বাদ দিয়ে বরং সুপার পদ্ধতি কল করার বিষয়ে চিন্তা করে।
মার্টিন বনাম লুইস

1
পাইথনের সিনট্যাক্সটি যদি এত সহজ ছিল [super init]তবে এটি আরও সাধারণ হবে। শুধু একটি অনুমানমূলক চিন্তা; পাইথন ২.x এর সুপার কনস্ট্রাক্টটি আমার কাছে কিছুটা বিশ্রী।
u0b34a0f6ae

এখানে একটা মজার (এবং সম্ভবত contradicting) উদাহরণস্বরূপ মনে করা হয় bytes.com/topic/python/answers/... Init
mlvljr

"alচ্ছিক" যাতে আপনাকে এটি কল করতে হবে না, তবে আপনি যদি এটি কল করেন না, এটি স্বয়ংক্রিয়ভাবে কল হবে না।
ম্যাককে

140

__init__বর্তমান ক্লাসে যা করা হচ্ছে তা ছাড়া আপনার যদি সুপারস থেকে কিছু করা প্রয়োজন হয় তবে আপনাকে __init__,এটিকে নিজেরাই কল করতে হবে, যেহেতু এটি স্বয়ংক্রিয়ভাবে ঘটবে না। তবে আপনার যদি সুপারের কাছ থেকে কিছু __init__,না প্রয়োজন তা কল করার দরকার নেই। উদাহরণ:

>>> class C(object):
        def __init__(self):
            self.b = 1


>>> class D(C):
        def __init__(self):
            super().__init__() # in Python 2 use super(D, self).__init__()
            self.a = 1


>>> class E(C):
        def __init__(self):
            self.a = 1


>>> d = D()
>>> d.a
1
>>> d.b  # This works because of the call to super's init
1
>>> e = E()
>>> e.a
1
>>> e.b  # This is going to fail since nothing in E initializes b...
Traceback (most recent call last):
  File "<pyshell#70>", line 1, in <module>
    e.b  # This is going to fail since nothing in E initializes b...
AttributeError: 'E' object has no attribute 'b'

__del__একইভাবে, (তবে __del__চূড়ান্তকরণের উপর নির্ভর করার বিষয়ে সতর্ক থাকুন - পরিবর্তে বিবৃতি দিয়ে এটি করার বিষয়ে বিবেচনা করুন)।

আমি খুব কমই ব্যবহার __new__. করি আমি সমস্ত সূচনাটি এর মধ্যে করি__init__.


3
ক্লাস ডি (সি) এর সংজ্ঞাটি এর মতো সংশোধন করতে হবেsuper(D,self).__init__()
ইকুয়েম

11
সুপার () .__ Init __ () শুধুমাত্র পাইথন 3. কাজ পাইথন 2 আপনি সুপার (ডি, স্ব) প্রয়োজন .__ Init __ ()
Jacinda

"যদি আপনার সুপারের থিমের থেকে কিছু দরকার হয় ..." - এটি একটি খুব সমস্যাযুক্ত বক্তব্য কারণ এটি আপনার / উপশ্রেণীর জন্য "কিছু" প্রয়োজন কিনা তা নয়, তবে বেস শ্রেণিকে বৈধ হওয়ার জন্য কিছু দরকার কিনা তা নয় of বেস ক্লাস উদাহরণ এবং সঠিকভাবে কাজ। উত্পন্ন শ্রেণীর প্রয়োগকারী হিসাবে, বেস বর্গ অভ্যন্তরগুলি এমন জিনিস যা আপনি জানতে পারবেন না / জানেন না, এবং আপনি লিখেছেন বা অভ্যন্তরীণ উভয়ই নথিভুক্ত করার কারণে, বেসের নকশাটি ভবিষ্যতে পরিবর্তিত হতে পারে এবং একটি খারাপ লেখার কারণে ভেঙে যেতে পারে উত্পন্ন ক্লাস সুতরাং সর্বদা নিশ্চিত করুন যে বেস ক্লাসটি সম্পূর্ণভাবে শুরু করা হয়েছে।
নিক

105

আননের উত্তরে: " বর্তমান শ্রেণীর কাজগুলি ছাড়াও যদি আপনার সুপারের
কিছু করা দরকার হয় তবে আপনাকে এটিকে নিজেরাই ডাকতে হবে, যেহেতু এটি স্বয়ংক্রিয়ভাবে ঘটবে না"__init____init__

এটি অবিশ্বাস্য: তিনি উত্তরাধিকারের নীতির বিপরীতে কথা বলছেন।


এটি এমন নয় যে "__init__ সুপারের (...) থেকে কিছু স্বয়ংক্রিয়ভাবে ঘটবে না" , এটি স্বয়ংক্রিয়ভাবে ঘটবে, তবে এটি ঘটেনি কারণ __init__ব্যাস-ক্লাসটি ডারাইভড-ক্লাসের সংজ্ঞা দ্বারা অতিক্রম করা হয়েছে__init__

তাহলে, কেন একটি derided_class 'সংজ্ঞায়িত করা হচ্ছে __init__, যেহেতু এটি যখন কেউ উত্তরাধিকারের দিকে অবলম্বন করবে তখন কী লক্ষ্য করা হচ্ছে তা ওভাররাইড করে ??

এটি কারন এমন কিছু সংজ্ঞায়িত করা দরকার যা বেস-ক্লাসে করা হয় না __init__, এবং এটি অর্জনের একমাত্র সম্ভাবনা হ'ল তার কার্যকরকরণকে ডেরাইভেড-ক্লাসের __init__ফাংশনে রেখে দেওয়া।
অন্য কথায়, এক 'বেস ক্লাসের কিছু দরকার __init__ছাড়াও কি স্বয়ংক্রিয়ভাবে বেস-classe মধ্যে সম্পন্ন করা হবে' __init__যদি এই আধুনিক ওভাররাইড করা হয় নি।
বিপরীত নয়।


তারপরে, সমস্যাটি হ'ল বেস-ক্লাসে উপস্থিত কাঙ্ক্ষিত নির্দেশাবলী __init__ইনস্ট্যান্টেশনের মুহুর্তে আর সক্রিয় হয় না। এই নিষ্ক্রিয়করণ অফসেট করার জন্য, বিশেষ কিছু প্রয়োজন: স্পষ্টভাবে বেস-ক্লাসকে কল করা ' __init__, KEEP করার জন্য , ADD না করার জন্য , বেস-ক্লাস দ্বারা সম্পাদিত সূচনা' __init__। সরকারী দস্তাবে ঠিক তেমনটাই বলা হয়েছে:

একটি উত্পন্ন শ্রেণিতে একটি ওভাররাইডিং পদ্ধতি আসলে একই নামের বেস ক্লাস পদ্ধতিটি পরিবর্তনের পরিবর্তে প্রসারিত করতে চাইতে পারে want বেস ক্লাস পদ্ধতিটি সরাসরি কল করার জন্য একটি সহজ উপায় রয়েছে: কেবল বেসক্লাসনাম.মোথডনাম (স্ব, যুক্তি) কল করুন।
http://docs.python.org/tutorial/classes.html#inheritance

এটাই সব গল্প:

  • যখন বেস-ক্লাস দ্বারা সম্পাদিত আরম্ভের লক্ষ্য রাখা হয়, এটি খাঁটি উত্তরাধিকার, বিশেষ কিছু প্রয়োজন হয় না, কেবলমাত্র __init__উত্পন্ন শ্রেণীর কোনও ক্রিয়াকলাপ সংজ্ঞায়িত করতে এড়ানো উচিত

  • যখন লক্ষ্যটি বেস-শ্রেণীর দ্বারা সম্পাদিত সূচনাটি পুনরায় প্রতিস্থাপন করা হয় তখন __init__অবশ্যই উত্পন্ন শ্রেণিতে সংজ্ঞায়িত করা উচিত

  • যখন বেস-ক্লাস দ্বারা সম্পাদিত প্রারম্ভিককরণের প্রক্রিয়াগুলি সংযোজন করা হয়, তখন একটি উত্পন্ন শ্রেণি ' __init__ অবশ্যই সংজ্ঞায়িত করা উচিত, বেস-ক্লাসে একটি সুস্পষ্ট কলকে অন্তর্ভুক্ত করে__init__


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


1
আমি নিশ্চিত যে এই পোস্টটি upvated হবে। আমি আশঙ্কা করছি যে কারণগুলি সম্পর্কে আমার খুব বেশি ব্যাখ্যা থাকবে না। বোঝা যায় না এমন টেক্সট বিশ্লেষণ করার চেয়ে ডাউনটা করা সহজ। শেষ পর্যন্ত বুঝতে পারার আগে আমি আননের পোস্টটি বুঝতে চেষ্টা করেছিলাম যে এটি স্পষ্টতই লেখা হয়েছিল এবং খুব বেশি প্রামাণিক নয়। যেহেতু উত্তরাধিকার সম্পর্কে জানে তার পক্ষে এটি প্রায় সঠিক হিসাবে ব্যাখ্যা করা যেতে পারে; কিন্তু উত্তরাধিকার সম্পর্কে অবিচলিত ধারণা থাকা কেউ পড়লে আমি বিভ্রান্তি বোধ করি, এটি সাধারণভাবে পাথরের জলের মতো স্পষ্ট নয়
আইকন

2
"আমি নিশ্চিত যে এই পোস্টটি উজ্জীবিত হতে চলেছে ..." মূল বিষয়টি হ'ল আপনি পার্টিতে কিছুটা দেরী করেছেন এবং বেশিরভাগ লোকেরা প্রথম কয়েকটি উত্তরের বাইরে না পড়তে পারে। উপায় দ্বারা দুর্দান্ত ব্যাখ্যা +1
জেরাত

দুর্দান্ত উত্তর এটি।
Trilarion

3
আপনি হারুনের কাছ থেকে উদ্ধৃত বাক্যে "উল্লেখযোগ্য" শব্দগুলি মিস করেছেন। হারুনের বক্তব্য পুরোপুরি সঠিক এবং আপনি যা বলছেন তা শেষ হয়।
গ্রিনএজেজেড

1
পাইথনের নকশার পছন্দটি বোধগম্য করে তোলে এটিই প্রথম ব্যাখ্যা।
জোসেফ গারভিন

20

সম্পাদনা করুন : (কোড পরিবর্তনের পরে)
আপনার পিতামাতার __init__(বা অন্য কোনও ফাংশন) আপনাকে কল করতে হবে কিনা তা আমাদের জানানোর কোনও উপায় নেই । উত্তরাধিকার স্পষ্টতই এই জাতীয় কল ছাড়াই কাজ করবে। এটি সমস্তই আপনার কোডের যুক্তির উপর নির্ভর করে: উদাহরণস্বরূপ, যদি আপনার সমস্ত __init__কিছু প্যারেন্ট ক্লাসে হয় তবে আপনি কেবলমাত্র শিশু-শ্রেণি __init__পুরোপুরি এড়িয়ে যেতে পারেন ।

নিম্নলিখিত উদাহরণ বিবেচনা করুন:

>>> class A:
    def __init__(self, val):
        self.a = val


>>> class B(A):
    pass

>>> class C(A):
    def __init__(self, val):
        A.__init__(self, val)
        self.a += val


>>> A(4).a
4
>>> B(5).a
5
>>> C(6).a
12

আমি আমার উদাহরণ থেকে সুপার কল সরিয়ে আমি জানতে চাই যদি এক অভিভাবক শ্রেণী বাস্তবায়ন কল করা উচিত চেয়েছিলাম Init বা না।
জর্জি স্কলি 14

আপনি তখন শিরোনাম সম্পাদনা করতে চাইবেন। তবে আমার উত্তর এখনও আছে।
সাইলেন্টগোস্ট

5

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

আপডেট: একই বেসিক লজিক কোনও পদ্ধতি কলের জন্য প্রযোজ্য। কনস্ট্রাক্টরদের মাঝে মাঝে বিশেষ বিবেচনার প্রয়োজন হয় (যেহেতু তারা প্রায়শই স্ট্যাট সেট করে যা আচরণ নির্ধারণ করে) এবং ডেস্ট্রাক্টর কারণ তারা সমান্তরাল কনস্ট্রাক্টর (যেমন সংস্থানসমূহের বরাদ্দে, যেমন ডাটাবেস সংযোগ)। তবে একই render()উইজেটের পদ্ধতিতে প্রয়োগ হতে পারে ।

আরও আপডেট: ওপিপি কী? আপনি কি ওওপি বলতে চান? না - একটি সাবক্লাস প্রায়শই সুপারক্লাসের নকশা সম্পর্কে কিছু জানতে হবে। অভ্যন্তরীণ বাস্তবায়নের বিশদ নয় - সুপারক্লাসের ক্লায়েন্টগুলির সাথে (ক্লাসগুলি ব্যবহার করে) রয়েছে এমন প্রাথমিক চুক্তি। এটি কোনওভাবেই ওওপি নীতিগুলি লঙ্ঘন করে না। সে কারণেই protectedসাধারণভাবে ওওপিতে একটি বৈধ ধারণা (যদিও এটি অবশ্যই পাইথনে নয়)।


আপনি বলেছিলেন যে কখনও কখনও সুপারক্লাস কল করার আগে কেউ নিজের কোডটি কল করতে চায়। এটি করার জন্য, একজনকে অভিভাবক শ্রেণীর প্রয়োগের জ্ঞান প্রয়োজন, যা ওপিপি লঙ্ঘন করে।
জর্জি স্কলি 16

4

আইএমও, আপনি এটি কল করা উচিত। যদি আপনার সুপারক্লাস হয় তবে আপনার objectউচিত নয়, তবে অন্যান্য ক্ষেত্রে আমি এটি কল না করাই ব্যতিক্রমী বলে মনে করি। অন্যদের দ্বারা ইতিমধ্যে উত্তর হিসাবে, এটি খুব সুবিধাজনক যদি আপনার শ্রেণি এমনকি __init__নিজেকে ওভাররাইড না করে, উদাহরণস্বরূপ যখন এটির (আরম্ভ) অভ্যন্তরীণ অবস্থা আরম্ভ করার দরকার নেই।


2

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

সর্বদা বেস শ্রেণিকে কল করার মূল কারণটি _init__হ'ল বেস শ্রেণি সাধারণত সদস্য পরিবর্তনশীল তৈরি করতে পারে এবং তাদের ডিফল্ট হিসাবে সূচনা করে। সুতরাং আপনি যদি বেস ক্লাস টিআইএম না কল করেন তবে সেই কোডটির কোনওটিই কার্যকর করা হবে না এবং আপনি বেস ক্লাসে শেষ করবেন যার কোনও সদস্যের ভেরিয়েবল নেই has

উদাহরণ :

class Base:
  def __init__(self):
    print('base init')

class Derived1(Base):
  def __init__(self):
    print('derived1 init')

class Derived2(Base):
  def __init__(self):
    super(Derived2, self).__init__()
    print('derived2 init')

print('Creating Derived1...')
d1 = Derived1()
print('Creating Derived2...')
d2 = Derived2()

এই মুদ্রণ ..

Creating Derived1...
derived1 init
Creating Derived2...
base init
derived2 init

এই কোড চালান

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