পাইথনে উত্তরাধিকার এবং ওভাররাইডিং __init__


129

আমি 'পাইথ ইন্ট পাইথন' পড়ছিলাম এবং ক্লাসগুলির অধ্যায়টিতে এটি উদাহরণ দেয়:

class FileInfo(UserDict):
    "store file metadata"
    def __init__(self, filename=None):
        UserDict.__init__(self)
        self["name"] = filename

লেখক তারপরে বলেছেন যে আপনি যদি __init__পদ্ধতিটিকে ওভাররাইড করতে চান তবে আপনাকে অবশ্যই __init__সঠিক প্যারামিটার সহ অভিভাবকদের কল করতে হবে ।

  1. যদি সেই FileInfoশ্রেণীর একাধিক পূর্বপুরুষ শ্রেণি থাকে তবে কী হবে?
    • আমার কি পূর্বপুরুষ শ্রেণীর সমস্ত __init__পদ্ধতি স্পষ্টভাবে কল করতে হবে ?
  2. এছাড়াও, আমি ওভাররাইড করতে চাইলে অন্য কোনও পদ্ধতিতে কি আমাকে এটি করতে হবে?

3
নোট করুন যে ওভারলোডিং ওভাররাইডিং থেকে পৃথক ধারণা।
দানা দ্য সনে

উত্তর:


158

সাবক্লাস-সুপারক্লাস কলিংয়ের বিষয়ে বইটি কিছুটা তারিখযুক্ত। এটি বিল্ট-ইন ক্লাসগুলি সাবক্লাসিংয়ের ক্ষেত্রে সামান্য তারিখেরও ated

আজকাল এরকম দেখাচ্ছে:

class FileInfo(dict):
    """store file metadata"""
    def __init__(self, filename=None):
        super(FileInfo, self).__init__()
        self["name"] = filename

নিম্নলিখিত নোট:

  1. আমরা সরাসরি উপশ্রেণী করতে বিল্ট-ইন ক্লাস, মত dict, list, tuple, ইত্যাদি

  2. superফাংশন হ্যান্ডলগুলি এই শ্রেণীর এর superclasses নিচে ট্র্যাকিং এবং উপযুক্তভাবে তাদের মধ্যে ফাংশন কলিং।


5
আমি কি আরও ভাল বই / টিউটোরিয়াল খুঁজছি?
লিউল

2
সুতরাং একাধিক উত্তরাধিকারের ক্ষেত্রে, সুপার () এগুলি কী আপনার পক্ষে অনুসরণ করে?
ডানা

ডিক .__ ইন __ (স্ব) আসলে, তবে এটির সাথে কিছুই ভুল নয় - সুপার (...) কলটি কেবল আরও একটি ধারাবাহিক বাক্য গঠন সরবরাহ করে। (আমি নিশ্চিত কিভাবে এটা একাধিক উত্তরাধিকার জন্য কাজ করে, আমি মনে করি এটা কেবল এক সুপারক্লাস খুঁজে পেতে পারেন নই Init )
ডেভিড জেড

4
সুপার () এর উদ্দেশ্যটি হ'ল এটি একাধিক উত্তরাধিকার পরিচালনা করে। অসুবিধাটি হ'ল, বাস্তবে একাধিক উত্তরাধিকার এখনও খুব সহজেই ভেঙে যায় (দেখুন < fuhm.net/super-harmful )।
স্টেথ

2
হ্যাঁ, একাধিক উত্তরাধিকার এবং বেস ক্লাসগুলি কনস্ট্রাক্টরের যুক্তি গ্রহণের ক্ষেত্রে, আপনি সাধারণত নিজেকে নির্মাতাকে ম্যানুয়ালি কল করতে দেখেন find
টর্স্টেন মেরেক

18

প্রতিটি শ্রেণীর যে অংশটি আপনার উত্তরাধিকার সূত্রে পাওয়া দরকার, আপনি প্রতিটি শ্রেণীর একটি লুপ চালাতে পারেন যা শিশু শ্রেণির সূচনা করার পরে দীক্ষা করা দরকার ... অনুলিপি দেওয়া যেতে পারে এমন একটি উদাহরণ আরও ভালভাবে বোঝা যেতে পারে ...

class Female_Grandparent:
    def __init__(self):
        self.grandma_name = 'Grandma'

class Male_Grandparent:
    def __init__(self):
        self.grandpa_name = 'Grandpa'

class Parent(Female_Grandparent, Male_Grandparent):
    def __init__(self):
        Female_Grandparent.__init__(self)
        Male_Grandparent.__init__(self)

        self.parent_name = 'Parent Class'

class Child(Parent):
    def __init__(self):
        Parent.__init__(self)
#---------------------------------------------------------------------------------------#
        for cls in Parent.__bases__: # This block grabs the classes of the child
             cls.__init__(self)      # class (which is named 'Parent' in this case), 
                                     # and iterates through them, initiating each one.
                                     # The result is that each parent, of each child,
                                     # is automatically handled upon initiation of the 
                                     # dependent class. WOOT WOOT! :D
#---------------------------------------------------------------------------------------#



g = Female_Grandparent()
print g.grandma_name

p = Parent()
print p.grandma_name

child = Child()

print child.grandma_name

2
এটি লুপ ইন Child.__init__জন্য প্রয়োজনীয় বলে মনে হচ্ছে না । আমি যখন উদাহরণ থেকে এটি সরিয়ে ফেলি তখনও শিশু "দাদী" মুদ্রণ করে। দাদু পিতামহ Parentক্লাস দ্বারা পরিচালিত হয় না ?
অ্যাডাম

4
আমি মনে করি দাদাগিরির থিমগুলি ইতিমধ্যে প্যারেন্টের ডিআইএম দ্বারা পরিচালিত হয়, তাই না?
johk95

15

আপনি সত্যিই না আছে ফোন করতে __init__বেস বর্গ (গুলি) পদ্ধতি, কিন্তু আপনি সাধারণত চান তা করতে কারণ বেস ক্লাস কিছু গুরুত্বপূর্ণ initializations যে কাজ শ্রেণীর পদ্ধতি বাকি জন্য প্রয়োজন হয় করব।

অন্যান্য পদ্ধতির জন্য এটি আপনার উদ্দেশ্যগুলির উপর নির্ভর করে। আপনি যদি কেবল বেস ক্লাসের আচরণে কিছু যুক্ত করতে চান তবে আপনি নিজের কোডে অতিরিক্ত ক্লাস পদ্ধতিটি কল করতে চাইবেন। আপনি যদি মৌলিকভাবে আচরণটি পরিবর্তন করতে চান, তবে আপনি বেস ক্লাসের পদ্ধতিটিকে কল করতে পারবেন না এবং ড্রেইড ক্লাসে সমস্ত কার্যকারিতা সরাসরি প্রয়োগ করতে পারেন।


4
প্রযুক্তিগত সম্পূর্ণতার জন্য, থ্রেডিংয়ের মতো কিছু শ্রেণি h থ্রেড, যদি আপনি কখনও পিতামাতার ইআরকে কল এড়াতে না চান তবে বিশাল ত্রুটি ছুঁড়ে দেবে ।
ডেভিড বার্গার 21

5
আমি এই সমস্ত "আপনাকে বেসের কনস্ট্রাক্টরকে কল করতে হবে না" কথাটি অত্যন্ত বিরক্তিকর মনে হচ্ছে। আমি জানি কোন ভাষায় আপনাকে এটি কল করতে হবে না। তাদের সবাই সদস্যদের সূচনা না করে অনেকগুলি একইভাবে স্ক্রু (বা না) করবে। বেস ক্লাস আরম্ভ না করার পরামর্শ দেওয়া অনেক দিক থেকে ভুল wrong যদি এখন কোনও শ্রেণীর সূচনা প্রয়োজন না তবে ভবিষ্যতে এটির প্রয়োজন হবে। কনস্ট্রাক্টর শ্রেণি কাঠামো / ভাষা নির্মানের ইন্টারফেসের অংশ, এবং সঠিকভাবে ব্যবহার করা উচিত is এটির সঠিক ব্যবহার হ'ল এটি কোনও সময় আপনার উত্পন্ন উত্পাদকের কাছে কল করা। তাহলে এটা কর.
AndreasT

2
"বেস ক্লাস আরম্ভ না করার পরামর্শ দেওয়া অনেক দিক থেকে ভুল।" বেস ক্লাস আরম্ভ না করার পরামর্শ কেউ দেয়নি। উত্তরটি মনোযোগ সহকারে পড়ুন। এটা সব উদ্দেশ্য সম্পর্কে। 1) আপনি যদি বেস ক্লাসের সূচনা যুক্তিটি যেমনটি ছেড়ে যেতে চান তবে আপনি আপনার উত্পন্ন শ্রেণিতে init পদ্ধতিকে ওভাররাইড করবেন না। ২) আপনি বেস ক্লাস থেকে আর ডি যুক্তিকে প্রসারিত করতে চাইলে আপনি নিজের ডিআইডি পদ্ধতিটি সংজ্ঞায়িত করুন এবং তারপরে এটি থেকে বেস ক্লাসের 'ডিআর পদ্ধতিটি কল করুন। 3) আপনি যদি বেস ক্লাসের 'ডিআইজি লজিকটি প্রতিস্থাপন করতে চান, তবে বেস ক্লাস থেকে কাউকে কল না করার সময় আপনি নিজের ডিআইডি পদ্ধতিটি সংজ্ঞায়িত করুন।
wombatonfire

4

যদি ফাইলআইএনফো ক্লাসে একাধিক পূর্বপুরুষ শ্রেণি থাকে তবে আপনার অবশ্যই তাদের সমস্ত __init __ () ফাংশন কল করতে হবে। __Del __ () ফাংশনের জন্যও আপনার একই কাজ করা উচিত, যা ধ্বংসকারী।


2

হ্যাঁ, আপনাকে অবশ্যই __init__প্রতিটি প্যারেন্ট ক্লাসের জন্য কল করতে হবে । আপনি যদি পিতা-মাতা উভয়ের মধ্যে বিদ্যমান এমন কোনও ক্রিয়াকে ওভাররাইড করে থাকেন তবে ফাংশনগুলির ক্ষেত্রেও এটি একই হয়।

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