পাইথনের সুপার () একাধিক উত্তরাধিকার নিয়ে কীভাবে কাজ করে?


885

আমি পাইথন অবজেক্ট ওরিয়েন্টেড প্রোগ্রামিংয়ে বেশ নতুন এবং super()ফাংশন (নতুন স্টাইলের ক্লাস) বুঝতে বিশেষত যখন একাধিক উত্তরাধিকার আসে তখন আমার সমস্যা হয় ।

উদাহরণস্বরূপ যদি আপনার মতো কিছু থাকে:

class First(object):
    def __init__(self):
        print "first"

class Second(object):
    def __init__(self):
        print "second"

class Third(First, Second):
    def __init__(self):
        super(Third, self).__init__()
        print "that's it"

যা আমি পাই না তা হ'ল: Third()ক্লাস কি উভয় নির্মাণকারী পদ্ধতিই উত্তরাধিকারী হবে ? যদি হ্যাঁ, তবে কোনটি সুপার () দিয়ে চালানো হবে এবং কেন?

এবং যদি আপনি অন্য একটি চালাতে চান? আমি জানি পাইথন পদ্ধতি রেজোলিউশন অর্ডার ( এমআরও ) এর সাথে এর কিছু সম্পর্ক রয়েছে ।


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

9
@ বাছসৌ প্রযুক্তিগতভাবে সঠিক যে এটি একটি ছোট ওভারহেড তবে সুপার () বেশি পাইথোনিক এবং এটি সময়ের সাথে সাথে পুনরায় ফ্যাক্টরিং এবং কোডের পরিবর্তনের অনুমতি দেয়। সুপার () ব্যবহার করুন যদি না আপনার সত্যিকার অর্থে একটি নির্দিষ্ট শ্রেণীর নির্দিষ্ট পদ্ধতি প্রয়োজন হয়।
পল হিপ্প

2
এর সাথে আর একটি সমস্যা super()হ'ল এটি প্রতিটি সাবক্লাসকে এটি ব্যবহার করতে বাধ্য করে, যখন ব্যবহার না করার সময় super(), সাবক্লাসিংকারী প্রত্যেকে নিজেরাই সিদ্ধান্ত নিতে পারে। এটি ব্যবহারকারী কোনও বিকাশকারী যদি এটি ব্যবহার করা সম্পর্কে জানেন না super()বা জানেন না তবে ম্রোতে সমস্যাগুলি দেখা দিতে পারে যা ট্র্যাক করা খুব কঠিন are
বচসউ

উত্তর:


711

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

আপনার উদাহরণে, Third()কল করবে First.__init__। পাইথন ক্লাসের পিতামাতার প্রতিটি বৈশিষ্ট্য অনুসন্ধান করে কারণ সেগুলি বাম থেকে ডানদিকে তালিকাভুক্ত। এই ক্ষেত্রে, আমরা খুঁজছি __init__। সুতরাং, যদি আপনি সংজ্ঞায়িত

class Third(First, Second):
    ...

পাইথনটি দেখে শুরু হবে First, এবং যদি Firstবৈশিষ্ট্যটি না থাকে তবে এটি সন্ধান করবে Second

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

সুতরাং, উদাহরণস্বরূপ, যদি আপনি:

class First(object):
    def __init__(self):
        print "first"

class Second(First):
    def __init__(self):
        print "second"

class Third(First):
    def __init__(self):
        print "third"

class Fourth(Second, Third):
    def __init__(self):
        super(Fourth, self).__init__()
        print "that's it"

এমআরও হবে [Fourth, Second, Third, First].

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

একটি অস্পষ্ট এমআরওর উদাহরণ যুক্ত করতে সম্পাদিত:

class First(object):
    def __init__(self):
        print "first"

class Second(First):
    def __init__(self):
        print "second"

class Third(First, Second):
    def __init__(self):
        print "third"

উচিত Third'র ম্রো হতে [First, Second]বা [Second, First]? এর সুস্পষ্ট প্রত্যাশা নেই এবং পাইথন ত্রুটি বাড়িয়ে তুলবে:

TypeError: Error when calling the metaclass bases
    Cannot create a consistent method resolution order (MRO) for bases Second, First

সম্পাদনা: আমি বেশিরভাগ লোককে দেখছি যে তর্ক করছে যে উপরের উদাহরণগুলিতে super()কলগুলির অভাব রয়েছে , সুতরাং আমাকে ব্যাখ্যা করতে দিন: উদাহরণগুলির মূল বিষয়টি এমআরও কীভাবে নির্মিত তা দেখানো। তারা "প্রথম \ n সেকেন্ড \ তৃতীয়" বা যাই হোক না কেন মুদ্রণের উদ্দেশ্যে নয় । আপনি - এবং অবশ্যই অবশ্যই উদাহরণটি নিয়ে খেলতে পারেন, super()কল যুক্ত করতে পারেন, কী ঘটেছিল তা দেখতে এবং পাইথনের উত্তরাধিকারের মডেলটির আরও গভীর উপলব্ধি অর্জন করতে পারেন। তবে আমার লক্ষ্য এখানে এটিকে সহজ রাখা এবং এমআরও কীভাবে নির্মিত তা দেখানো। আমি এটি ব্যাখ্যা হিসাবে এটি নির্মিত হয়েছে:

>>> Fourth.__mro__
(<class '__main__.Fourth'>,
 <class '__main__.Second'>, <class '__main__.Third'>,
 <class '__main__.First'>,
 <type 'object'>)

12
আপনি প্রথম, দ্বিতীয় এবং তৃতীয় [ পেস্টবিন . com/জেটিজাইজ 5 ওয়ে ] তে সুপার () কল করা শুরু করলে এটি আরও আকর্ষণীয় (এবং, তর্কযুক্ত, আরও বিভ্রান্তিকর) হয়ে ওঠে ।
gatoatigrado

52
আমি মনে করি প্রথম শ্রেণিতে সুপার কলের অভাব এই উত্তরটির সাথে সত্যই একটি বড় সমস্যা; কীভাবে / কেন এই প্রশ্নের গুরুত্বপূর্ণ সমালোচনা হারিয়ে যায় তা আলোচনা না করেই।
স্যাম হার্টম্যান

3
এই উত্তরটি কেবল ভুল। পিতামাতাদের সুপার () কল ছাড়া কিছু হবে না। @ প্রাণহীনদের উত্তরটি সঠিক।
সেরিন

8
@ সেরিন এই উদাহরণটির মূল বিষয়টি এমআরও কীভাবে নির্মিত তা দেখানো। উদাহরণটি "প্রথম \ n সেকেন্ড \ তৃতীয়" বা যা কিছু মুদ্রণের উদ্দেশ্যে নয়। আর ম্রো প্রকৃতপক্ষে ঠিক কিনা: চতুর্থ .__ mro__ == (<বর্গ ' প্রধান .Fourth'>, <বর্গ ' প্রধান .Second'>, <বর্গ ' প্রধান .Third'>, <বর্গ ' প্রধান .First'>, < 'অবজেক্ট'> টাইপ করুন
rbp

2
আমি যতদূর দেখতে পাচ্ছি, এই উত্তরটি ওপির একটি প্রশ্নের অনুপস্থিত, যা "এবং আপনি যদি অন্যটি চালাতে চান তবে কি হবে?" আমি এই প্রশ্নের উত্তর দেখতে চাই। আমাদের কি কেবল স্পষ্টভাবে বেস ক্লাসের নাম দেওয়ার কথা রয়েছে?
রায়

251

আপনার কোড এবং অন্যান্য উত্তরগুলি সমস্ত বগি। super()কো-অপারেটিভ সাবক্লাসিংয়ের কাজ করার জন্য প্রয়োজনীয় প্রথম দুটি ক্লাসে তারা কলগুলি অনুপস্থিত ।

কোডের একটি স্থির সংস্করণ এখানে:

class First(object):
    def __init__(self):
        super(First, self).__init__()
        print("first")

class Second(object):
    def __init__(self):
        super(Second, self).__init__()
        print("second")

class Third(First, Second):
    def __init__(self):
        super(Third, self).__init__()
        print("third")

super()কল প্রতিটি পদক্ষেপ, যা কেন প্রথম ও দ্বিতীয় এটা খুব আছে এ ম্রো পরবর্তী পদ্ধতি খুঁজে বের করে, অন্যথায় সম্পাদন শেষে স্টপ Second.__init__()

এটি আমি পেয়েছি:

>>> Third()
second
first
third

89
এই ক্লাসগুলির নিজেদের শুরু করার জন্য বিভিন্ন পরামিতিগুলির প্রয়োজন হলে কী করবেন?
ক্যালফজু

2
"সমবায় সাবক্লাসিং"
কোয়ান্ট মেট্রোপলিস

5
এইভাবে BOTH বেস ক্লাসগুলির আরম্ভ পদ্ধতিগুলি কার্যকর করা হবে, যখন মূল উদাহরণটি এমআরওতে উপস্থিত প্রথম থিমটিকেই ডাকে । আমি অনুমান করি যে "সমবায় সাবক্লাসিং" শব্দটি দ্বারা বোঝানো হয়েছে, তবে একটি ব্যাখ্যা কার্যকর হতে পারত ('সুস্পষ্টর চেয়ে ভাল ভাল,' আপনি জানেন;))
কোয়ান্ট মেট্রোপলিস

1
হ্যাঁ, আপনি যদি সুপারের মাধ্যমে ডেকে পাঠানো কোনও পদ্ধতিতে বিভিন্ন পরামিতিগুলি অতিক্রম করে থাকেন তবে সেই পদ্ধতির সমস্ত বাস্তবায়নের ক্ষেত্রে এমআরও অবজেক্ট () এর দিকে যাচ্ছে যা সামঞ্জস্যপূর্ণ স্বাক্ষর থাকা দরকার। কীওয়ার্ড প্যারামিটারগুলির মাধ্যমে এটি অর্জন করা যেতে পারে: পদ্ধতিটি ব্যবহার করে তার চেয়ে বেশি পরামিতি গ্রহণ করুন এবং অতিরিক্তগুলি উপেক্ষা করুন। এটি সাধারণত এটি করতে কুৎসিত হিসাবে বিবেচিত হয় এবং বেশিরভাগ ক্ষেত্রে নতুন পদ্ধতি যুক্ত করা আরও ভাল তবে থ্রি (প্রায়?) একটি বিশেষ পদ্ধতির নাম হিসাবে তবে ব্যবহারকারী সংজ্ঞায়িত পরামিতিগুলির সাথে অনন্য।
নিষ্প্রাণ

15
পাইথনের একাধিক উত্তরাধিকারের নকশা সত্যই খারাপ। বেস ক্লাসগুলি প্রায় এটি জেনে রাখা উচিত যে কে এটি অর্জন করতে চলেছে, এবং প্রাপ্ত অন্যান্য কতগুলি বেস শ্রেণিভুক্ত হবে এবং কোন ক্রমে ... অন্যথায় superহয় চালাতে ব্যর্থ হবে (প্যারামিটারের অমিলের কারণে), বা এটি কল করবে না ঘাঁটি কয়েকটি (কারণ আপনি superযে বেসটি লিঙ্কটি ভেঙেছেন তার কোনওটিতে লিখেনি)!
নওয়াজ

185

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

আপনার যা বোঝার দরকার তা হ'ল সম্পূর্ণ উত্তরাধিকারের শ্রেণিবিন্যাসের প্রসঙ্গে ব্যবহৃত মেথড রেজোলিউশন অর্ডারিং (এমআরও) অ্যালগরিদম অনুযায়ী পরবর্তী পদ্ধতি super(MyClass, self).__init__()সরবরাহ করে । __init__

এই শেষ অংশটি বুঝতে গুরুত্বপূর্ণ। আসুন উদাহরণটি আবার বিবেচনা করুন:

#!/usr/bin/env python2

class First(object):
  def __init__(self):
    print "First(): entering"
    super(First, self).__init__()
    print "First(): exiting"

class Second(object):
  def __init__(self):
    print "Second(): entering"
    super(Second, self).__init__()
    print "Second(): exiting"

class Third(First, Second):
  def __init__(self):
    print "Third(): entering"
    super(Third, self).__init__()
    print "Third(): exiting"

গাইডো ভ্যান রসমের পদ্ধতি রেজোলিউশন অর্ডার সম্পর্কে এই নিবন্ধ অনুসারে, সমাধানের আদেশটি__init__ "পাইথন ২.৩ এর পূর্বে" একটি "গভীরতা-প্রথম বাম থেকে ডান ট্র্যাভারসাল" ব্যবহার করে গণনা করা হয়:

Third --> First --> object --> Second --> object

সর্বশেষটি বাদে সমস্ত নকল অপসারণের পরে, আমরা পাই:

Third --> First --> Second --> object

সুতরাং, দেয় অনুসরণ কি হবে যখন আমরা একটি দৃষ্টান্ত instantiate Thirdবর্গ, যেমন x = Third()

  1. এমআরও অনুযায়ী Third.__init__এক্সিকিউট।
    • কপি করে প্রিন্ট Third(): entering
    • তারপরে super(Third, self).__init__()এক্সিকিউট করে এবং এমআরও রিটার্ন First.__init__যা বলা হয়।
  2. First.__init__ সঞ্চালন করে।
    • কপি করে প্রিন্ট First(): entering
    • তারপরে super(First, self).__init__()এক্সিকিউট করে এবং এমআরও রিটার্ন Second.__init__যা বলা হয়।
  3. Second.__init__ সঞ্চালন করে।
    • কপি করে প্রিন্ট Second(): entering
    • তারপরে super(Second, self).__init__()এক্সিকিউট করে এবং এমআরও রিটার্ন object.__init__যা বলা হয়।
  4. object.__init__ কার্যকর করা (কোডটিতে কোনও মুদ্রণ বিবৃতি নেই)
  5. এক্সিকিউশন ফিরে যায় Second.__init__যা মুদ্রণSecond(): exiting
  6. এক্সিকিউশন ফিরে যায় First.__init__যা মুদ্রণFirst(): exiting
  7. এক্সিকিউশন ফিরে যায় Third.__init__যা মুদ্রণThird(): exiting

তৃতীয় () তদন্ত করার ফলাফল এখানে কী কারণে ফলাফল:

Third(): entering
First(): entering
Second(): entering
Second(): exiting
First(): exiting
Third(): exiting

জটিল ক্ষেত্রে ভাল কাজ করার জন্য এমআরও অ্যালগরিদম পাইথন ২.৩ থেকে উন্নতি করা হয়েছে, তবে আমার ধারণা যে "গভীরতার-প্রথম বাম থেকে ডান দিকের ট্র্যাভারসাল" + "শেষের প্রত্যাশিত নকলগুলি ব্যবহার করা" এখনও বেশিরভাগ ক্ষেত্রেই কাজ করে (দয়া করে যদি এটি না হয় তবে মন্তব্য করুন)। গিডোর ব্লগ পোস্টটি অবশ্যই পড়তে ভুলবেন না!


6
আমি এখনও বুঝতে পারে না কেন: ইনসাইড init প্রথম সুপার (প্রথম, স্ব) এর .__ Init __ () কল Init দ্বিতীয় কারণ যে কি ম্রো নির্দেশনা নেই!
ব্যবহারকারী 389955

@ user389955 তৈরি করা অবজেক্টটি তৃতীয় প্রকারের রয়েছে যার সমস্ত ডিআইডি পদ্ধতি রয়েছে। সুতরাং আপনি যদি ধরে নেন যে এমআরও প্রতিটি সুপার কল সহ একটি সুনির্দিষ্ট ক্রমে সমস্ত আরম্ভকারী ক্রিয়াগুলির একটি তালিকা তৈরি করে, আপনি শেষের দিকে পৌঁছা পর্যন্ত আপনি এক ধাপ এগিয়ে যাচ্ছেন।
শ্রীকুমার আর

15
আমি মনে করি ধাপ 3 চাহিদা আরো ব্যাখ্যা: যদি Thirdউত্তরাধিকারী করা হয়নি থেকে Second, তারপর super(First, self).__init__কল করবে object.__init__এবং ফিরে, "প্রথমে" প্রিন্ট করা হবে। কিন্তু কারণ Thirdউভয় থেকে উত্তরাধিকারী Firstএবং Secondবরং কলিং পরিবর্তে, object.__init__পরে First.__init__ম্রো dictates যে একমাত্র চূড়ান্ত কল object.__init__সংরক্ষিত হয়, এবং মুদ্রণ বিবৃতি Firstএবং Secondযতক্ষণ না পৌঁছে নেই object.__init__আয়। যেহেতু Secondসর্বশেষে কল করা ছিল তাই object.__init__এটি ফিরে Secondআসার আগেই ভিতরে ফিরে আসে First
মাউন্টেনড্রু

1
মজার ব্যাপার হচ্ছে, PyCharm জানেন বলে মনে হয় এই সব (তার নির্দেশ, সম্পর্কে যা পরামিতি যা সুপার কল। এছাড়া ইনপুট সহভেদাংক কিছু ধারণা রয়েছে তার সাথে যেতে কথা তাই এটি স্বীকার List[subclass]হিসাবে একটি List[superclass]যদি subclassহয় একটি উপশ্রেণী superclass( Listথেকে আসে typingPEP 483 এর মডিউল
iirc

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

58

এটি ডায়মন্ড সমস্যা হিসাবে পরিচিত , পৃষ্ঠার পাইথনে একটি প্রবেশ রয়েছে, তবে সংক্ষেপে, পাইথন সুপারক্লাসের পদ্ধতিগুলি বাম থেকে ডানে ডেকে আনবে।


এটি ডায়মন্ড সমস্যা নয়। ডায়মন্ড সমস্যা চারটি ক্লাস জড়িত এবং ওপি এর প্রশ্নে কেবল তিনটি জড়িত।
ইয়ান গুডফেলো

146
objectচতুর্থ
জিপি 89

28

আরম্ভের জন্য বিভিন্ন ভেরিয়েবলের সাথে একাধিক উত্তরাধিকার এবং একই ফাংশন কলটির সাথে একাধিক মিক্স ইন করার বিষয়টি আমি কীভাবে সমাধান করেছি। আমাকে স্পষ্টভাবে পাস করা ** কাওয়ারগুলিতে ভেরিয়েবলগুলি যুক্ত করতে হয়েছিল এবং সুপার কলগুলির জন্য একটি শেষ পয়েন্ট হতে একটি মিক্সইন ইন্টারফেস যুক্ত করতে হয়েছিল।

এখানে Aএকটি extendable বেস ক্লাস হয় এবং Bএবং CMixIn শ্রেণীর উভয় যারা ফাংশন প্রদান হয় fAএবং Bউভয়ই vতাদের প্যারামিটার আশা করে __init__এবং Cআশা করে w। ফাংশনটির fএকটি প্যারামিটার লাগে yQতিনটি ক্লাস থেকে উত্তরাধিকার। এবং এর MixInFজন্য মেশিন ইন্টারফেস ।BC


class A(object):
    def __init__(self, v, *args, **kwargs):
        print "A:init:v[{0}]".format(v)
        kwargs['v']=v
        super(A, self).__init__(*args, **kwargs)
        self.v = v


class MixInF(object):
    def __init__(self, *args, **kwargs):
        print "IObject:init"
    def f(self, y):
        print "IObject:y[{0}]".format(y)


class B(MixInF):
    def __init__(self, v, *args, **kwargs):
        print "B:init:v[{0}]".format(v)
        kwargs['v']=v
        super(B, self).__init__(*args, **kwargs)
        self.v = v
    def f(self, y):
        print "B:f:v[{0}]:y[{1}]".format(self.v, y)
        super(B, self).f(y)


class C(MixInF):
    def __init__(self, w, *args, **kwargs):
        print "C:init:w[{0}]".format(w)
        kwargs['w']=w
        super(C, self).__init__(*args, **kwargs)
        self.w = w
    def f(self, y):
        print "C:f:w[{0}]:y[{1}]".format(self.w, y)
        super(C, self).f(y)


class Q(C,B,A):
    def __init__(self, v, w):
        super(Q, self).__init__(v=v, w=w)
    def f(self, y):
        print "Q:f:y[{0}]".format(y)
        super(Q, self).f(y)

আমি মনে করি এটি সম্ভবত একটি পৃথক প্রশ্নোত্তর হওয়া উচিত, কারণ এমআরও উত্তরাধিকারের সাথে বিভিন্ন ক্রিয়াকলাপে বিভিন্ন যুক্তি মোকাবেলা না করে নিজেই একটি বিশাল যথেষ্ট বিষয় (
নির্জীব 10

8
তাত্ত্বিকভাবে, হ্যাঁ ব্যবহারিকভাবে, অজস্রতে ডায়মন্ডের উত্তরাধিকারের মুখোমুখি প্রতিবার এই দৃশ্যটি উঠে এসেছে, তাই আমি এটি এখানে যুক্ত করেছি। যেহেতু, আমি এখানে প্রতিবার যাই তাই আমি পরিষ্কারভাবে হীরার উত্তরাধিকার এড়াতে পারি না। ভবিষ্যতের আমার জন্য এখানে কিছু অতিরিক্ত লিঙ্ক রয়েছে: rhettinger.wordpress.com/2011/05/26/super-considered-Super code.activestate.com/recips/…
brent.payne

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

বর্ণনামূলক নাম সহ
গিথুব রেপোতে

@ ব্রেন্ট.পেইন আমি মনে করি @ আর্থারটির অর্থ হল আপনার সম্পূর্ণ পদ্ধতির নামকরণকৃত পরামিতিগুলি ব্যবহার করার পরিবর্তে args/ ব্যবহারের উপর নির্ভরশীল kwargs
সর্বাধিক

24

আমি বুঝতে পারি এটি সরাসরি প্রশ্নের উত্তর দেয় না super()তবে আমি মনে করি এটি ভাগ করার পক্ষে যথেষ্ট প্রাসঙ্গিক।

প্রতিটি উত্তরাধিকার সূত্রে প্রাপ্ত শ্রেণিকে সরাসরি কল করার একটি উপায়ও রয়েছে:


class First(object):
    def __init__(self):
        print '1'

class Second(object):
    def __init__(self):
        print '2'

class Third(First, Second):
    def __init__(self):
        Second.__init__(self)

শুধু মনে রাখবেন যদি আপনি এটি এই ভাবে করেন, তখন আপনাকে যেমন আমি নিশ্চিত প্রশংসনীয় ম্যানুয়ালি প্রতিটি কলের করতে হবে First'র __init__()নামক করা হবে না।


5
এটি বলা হবে না কারণ আপনি প্রতিটি উত্তরাধিকারসূত্রে ক্লাস করেননি। সমস্যাটি বরং এটি Firstএবং Secondযদি উভয়ই অন্য শ্রেণীর উত্তরাধিকার সূত্রে প্রাপ্ত হয় এবং সরাসরি এটিকে কল করে তবে এই সাধারণ শ্রেণিটি (হীরার প্রারম্ভিক বিন্দু) দু'বার বলা হয়। সুপার এড়ানো হয়।
ট্রায়ারিলিয়ন

@ ট্রিলারিয়ন হ্যাঁ, আমি আত্মবিশ্বাসী ছিল যে এটি হবে না। যাইহোক, আমি নিশ্চিতভাবে জানতাম না এবং আমি খুব বেশি সম্ভাবনা থাকা সত্ত্বেও আমি তা জানাতে চাইনি। এটি objectদুটি বার বলা হচ্ছে সম্পর্কে একটি ভাল পয়েন্ট । আমি সে সম্পর্কে ভেবে দেখিনি। আমি কেবলমাত্র আপনি যে পিতামাতাদের ক্লাসে সরাসরি কল করতে চান সেই পয়েন্টটি তৈরি করতে চেয়েছিলাম।
Seaux

দুর্ভাগ্যবশত, এই বিরতি যদি Init কোনো ব্যক্তিগত পদ্ধতি :( অ্যাক্সেস করার চেষ্টা করে
এরিক Aronesty

21

সার্বিক

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

  • একটি শ্রেণির শিশুরা তাদের পিতামাতার সামনে আসে
  • বাম মা-বাবা সঠিক বাবা-মায়ের সামনে আসেন come
  • একটি ক্লাস এমআরওতে একবার উপস্থিত হয় appears

যদি এরকম কোনও অর্ডার উপস্থিত না থাকে, পাইথন ত্রুটি। এর অভ্যন্তরীণ কাজগুলি ক্লাস বংশের সি 3 লাইনারাইজেশন। এটি সম্পর্কে এখানে সব পড়ুন: https://www.python.org/download/releases/2.3/mro/

সুতরাং, নীচের দুটি উদাহরণে এটি হ'ল:

  1. শিশু
  2. বাম
  3. অধিকার
  4. মাতা

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

সঙ্গে superপ্রতিটি পদ্ধতির প্রথম

class Parent(object):
    def __init__(self):
        super(Parent, self).__init__()
        print "parent"

class Left(Parent):
    def __init__(self):
        super(Left, self).__init__()
        print "left"

class Right(Parent):
    def __init__(self):
        super(Right, self).__init__()
        print "right"

class Child(Left, Right):
    def __init__(self):
        super(Child, self).__init__()
        print "child"

Child() আউটপুট:

parent
right
left
child

সঙ্গে superপ্রতিটি পদ্ধতির গত

class Parent(object):
    def __init__(self):
        print "parent"
        super(Parent, self).__init__()

class Left(Parent):
    def __init__(self):
        print "left"
        super(Left, self).__init__()

class Right(Parent):
    def __init__(self):
        print "right"
        super(Right, self).__init__()

class Child(Left, Right):
    def __init__(self):
        print "child"
        super(Child, self).__init__()

Child() আউটপুট:

child
left
right
parent

আমি যে আপনি অ্যাক্সেস করতে পারেন দেখতে Leftব্যবহার super()থেকে Child। মনে হয় আমি অ্যাক্সেস করতে চান Rightভিতর থেকে Child। সুপার ব্যবহার Rightথেকে অ্যাক্সেস করার কোনও উপায় আছে Child? নাকি আমাকে সরাসরি Rightভিতরে থেকে ফোন করা উচিত super?
alpha_989 22

4
@ alpha_989 আপনি যদি কেবলমাত্র একটি নির্দিষ্ট শ্রেণীর পদ্ধতিতে অ্যাক্সেস করতে চান তবে আপনার সুপারটি ব্যবহার না করে সরাসরি সেই শ্রেণিটি উল্লেখ করা উচিত। সুপার হ'ল উত্তরাধিকারের শৃঙ্খলা অনুসরণ করে নির্দিষ্ট শ্রেণীর পদ্ধতিতে না চলে not
Zags

1
'একটি শ্রেণি এমআরও-তে কেবল একবার উপস্থিত হয়' উল্লেখ করার জন্য ধন্যবাদ। এটি আমার সমস্যার সমাধান করেছে। এখন আমি পরিশেষে বুঝতে পারি যে একাধিক উত্তরাধিকার কীভাবে কাজ করে। কেউ এমআরওর বৈশিষ্ট্য উল্লেখ করার প্রয়োজন ছিল!
তুষার ওয়াজিরানী

18

@ ক্যালফজু'র মন্তব্য সম্পর্কে , আপনি সাধারণত, ব্যবহার করতে পারেন **kwargs:

অনলাইন চলমান উদাহরণ

class A(object):
  def __init__(self, a, *args, **kwargs):
    print("A", a)

class B(A):
  def __init__(self, b, *args, **kwargs):
    super(B, self).__init__(*args, **kwargs)
    print("B", b)

class A1(A):
  def __init__(self, a1, *args, **kwargs):
    super(A1, self).__init__(*args, **kwargs)
    print("A1", a1)

class B1(A1, B):
  def __init__(self, b1, *args, **kwargs):
    super(B1, self).__init__(*args, **kwargs)
    print("B1", b1)


B1(a1=6, b1=5, b="hello", a=None)

ফলাফল:

A None
B hello
A1 6
B1 5

এগুলি আপনি অবস্থানগতভাবে ব্যবহার করতে পারেন:

B1(5, 6, b="hello", a=None)

তবে আপনাকে এমআরও মনে রাখতে হবে, এটি সত্যিই বিভ্রান্তিকর।

আমি কিছুটা বিরক্তিকর হতে পারি তবে আমি লক্ষ্য করেছি যে লোকেরা প্রতিবার ব্যবহার করতে ভুলে গিয়েছিল *argsএবং **kwargsযখন তারা কোনও পদ্ধতিকে ওভাররাইড করে, তবে এই 'ম্যাজিক ভেরিয়েবলগুলি' ব্যবহার করার জন্য সত্যই দরকারী এবং বুদ্ধিমান ব্যবহারের মধ্যে এটি অন্যতম।


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

15

অন্য একটি এখনও আবৃত পয়েন্ট ক্লাস আরম্ভের জন্য পরামিতিগুলি পাস করছে। যেহেতু superসাবক্লাসের গন্তব্য নির্ভর করে প্যারামিটারগুলি পাস করার একমাত্র ভাল উপায় সেগুলি একসাথে প্যাক করে। তারপরে সতর্কতা অবলম্বন করুন যে বিভিন্ন পরামিতিটির নামটি বিভিন্ন অর্থ সহ না হয়।

উদাহরণ:

class A(object):
    def __init__(self, **kwargs):
        print('A.__init__')
        super().__init__()

class B(A):
    def __init__(self, **kwargs):
        print('B.__init__ {}'.format(kwargs['x']))
        super().__init__(**kwargs)


class C(A):
    def __init__(self, **kwargs):
        print('C.__init__ with {}, {}'.format(kwargs['a'], kwargs['b']))
        super().__init__(**kwargs)


class D(B, C): # MRO=D, B, C, A
    def __init__(self):
        print('D.__init__')
        super().__init__(a=1, b=2, x=3)

print(D.mro())
D()

দেয়:

[<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]
D.__init__
B.__init__ 3
C.__init__ with 1, 2
A.__init__

__init__প্যারামিটারগুলির আরও সরাসরি অ্যাসাইনমেন্টে সরাসরি সুপার ক্লাসকে কল করা প্ররোচিত হয় তবে superসুপার ক্লাসে এবং / অথবা এমআরও পরিবর্তিত হয় এবং ক্লাস এ বাস্তবায়নের উপর নির্ভর করে একাধিকবার কল হতে পারে তবে ব্যর্থ হয় ।

উপসংহারে: সমবায় উত্তরাধিকার এবং সূচনার জন্য সুপার এবং নির্দিষ্ট পরামিতি খুব ভাল একসঙ্গে কাজ করছে না।


5
class First(object):
  def __init__(self, a):
    print "first", a
    super(First, self).__init__(20)

class Second(object):
  def __init__(self, a):
    print "second", a
    super(Second, self).__init__()

class Third(First, Second):
  def __init__(self):
    super(Third, self).__init__(10)
    print "that's it"

t = Third()

আউটপুট হয়

first 10
second 20
that's it

তৃতীয়কে কল করুন () তৃতীয়তে সংজ্ঞায়িত আরআইকে চিহ্নিত করে। এবং সেই রুটিনে সুপারকে কল করুন প্রথমে সংজ্ঞায়িত আরম্ভ করুন । এমআরও = [প্রথম, দ্বিতীয়]। এখন প্রথমটিতে সংজ্ঞায়িত সুপার-ইন-কে এমআরও অনুসন্ধান চালিয়ে যাওয়া এবং দ্বিতীয়টিতে সংজ্ঞায়িত আরম্ভের সন্ধান করা হবে এবং সুপার-এ যে কোনও কলই ডিফল্ট অবজেক্ট ইনকে আঘাত করবে । আমি আশা করি এই উদাহরণটি ধারণাটি পরিষ্কার করেছে।

যদি আপনি প্রথম থেকে সুপার না কল। চেইন বন্ধ হয়ে যায় এবং আপনি নিম্নলিখিত আউটপুট পাবেন।

first 10
that's it

1
এটি কারণ প্রথম শ্রেণিতে আপনি 'প্রিন্ট' প্রথমে 'সুপার' বলেছিলেন।
পাথুরে কিউই

2
এটি ছিল কলিং অর্ডার চিত্রিত করার জন্য
সেরাজ আহমদ

4

লার্নিংপেইথহেনহেডওয়েতে আমি সুপার () নামে একটি কিছু অন্তর্নির্মিত ফাংশন শিখি যদি ভুল না হয়। সুপার () ফাংশন কল করা উত্তরাধিকারকে পিতামাতা এবং 'ভাইবোনদের' মধ্য দিয়ে যেতে এবং আপনাকে আরও পরিষ্কার দেখতে সহায়তা করতে পারে। আমি এখনও একটি শিক্ষানবিস তবে পাইথন 2.7 এ এই সুপার () ব্যবহার করার বিষয়ে আমার অভিজ্ঞতা ভাগ করে নিতে ভালোবাসি।

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

সুপার () ফাংশন যুক্ত করে

super(First, self).__init__() #example for class First.

আপনি প্রতিটি এবং প্রত্যেককে যুক্ত করে সুপার () এর সাথে একাধিক উদাহরণ এবং 'পরিবার' সংযুক্ত করতে পারেন। এবং এটি পদ্ধতিগুলি কার্যকর করবে, সেগুলির মধ্য দিয়ে যান এবং নিশ্চিত হন যে আপনি মিস করেছেন না! তবে এগুলি যুক্ত করার আগে বা তার পরে কোনও পার্থক্য তৈরি করে আপনি জানতে পারবেন আপনি লার্নিংপ্যাথহেনডওয়ে অনুশীলন 44 করেছেন কিনা the মজা শুরু করা যাক !!

নীচে উদাহরণস্বরূপ, আপনি অনুলিপি এবং আটকানো এবং এটি চালানোর চেষ্টা করতে পারেন:

class First(object):
    def __init__(self):

        print("first")

class Second(First):
    def __init__(self):
        print("second (before)")
        super(Second, self).__init__()
        print("second (after)")

class Third(First):
    def __init__(self):
        print("third (before)")
        super(Third, self).__init__()
        print("third (after)")


class Fourth(First):
    def __init__(self):
        print("fourth (before)")
        super(Fourth, self).__init__()
        print("fourth (after)")


class Fifth(Second, Third, Fourth):
    def __init__(self):
        print("fifth (before)")
        super(Fifth, self).__init__()
        print("fifth (after)")

Fifth()

কীভাবে চলবে? পঞ্চম () এর উদাহরণটি এরকম হবে। প্রতিটি পদক্ষেপ ক্লাস থেকে ক্লাসে যায় যেখানে সুপার ফাংশন যুক্ত হয়।

1.) print("fifth (before)")
2.) super()>[Second, Third, Fourth] (Left to right)
3.) print("second (before)")
4.) super()> First (First is the Parent which inherit from object)

পিতামাতাকে পাওয়া গেছে এবং এটি তৃতীয় এবং চতুর্থ অবধি চলতে থাকবে !!

5.) print("third (before)")
6.) super()> First (Parent class)
7.) print ("Fourth (before)")
8.) super()> First (Parent class)

এখন সুপার () সহ সমস্ত ক্লাস অ্যাক্সেস করা হয়েছে! অভিভাবক শ্রেণীর সন্ধান পেয়েছে এবং সম্পাদন করা হয়েছে এবং এখন কোডগুলি শেষ করার জন্য এটি উত্তরাধিকার সূত্রে ফাংশনটি আনবক্স করতে থাকবে।

9.) print("first") (Parent)
10.) print ("Fourth (after)") (Class Fourth un-box)
11.) print("third (after)") (Class Third un-box)
12.) print("second (after)") (Class Second un-box)
13.) print("fifth (after)") (Class Fifth un-box)
14.) Fifth() executed

উপরোক্ত প্রোগ্রামের ফলাফল:

fifth (before)
second (before
third (before)
fourth (before)
first
fourth (after)
third (after)
second (after)
fifth (after)

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


বিস্তারিত ডেমো জন্য ধন্যবাদ!
তুষার ওয়াজিরানী

3

@ ভিশনস্কেপার উপরে যা বলেছে তাতে আমি যুক্ত করতে চাই :

Third --> First --> object --> Second --> object

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

C, L (C) শ্রেণীর লিনিয়ারাইজেশন (ম্রো) হ'ল

  • ক্লাস সি
  • প্লাস এর একত্রীকরণ
    • এর পিতামাতার P1, P2, .. = L (পি 1, পি 2, ...) লিনিয়ারীকরণ এবং
    • এর পিতামাতার তালিকা পি 1, পি 2, ..

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

তৃতীয় রৈখিক রচনাটি নিম্নরূপে গণনা করা যায়:

    L(O)  := [O]  // the linearization(mro) of O(object), because O has no parents

    L(First)  :=  [First] + merge(L(O), [O])
               =  [First] + merge([O], [O])
               =  [First, O]

    // Similarly, 
    L(Second)  := [Second, O]

    L(Third)   := [Third] + merge(L(First), L(Second), [First, Second])
                = [Third] + merge([First, O], [Second, O], [First, Second])
// class First is a good candidate for the first merge step, because it only appears as the head of the first and last lists
// class O is not a good candidate for the next merge step, because it also appears in the tails of list 1 and 2, 
                = [Third, First] + merge([O], [Second, O], [Second])
// class Second is a good candidate for the second merge step, because it appears as the head of the list 2 and 3
                = [Third, First, Second] + merge([O], [O])            
                = [Third, First, Second, O]

সুতরাং নিম্নলিখিত কোডে একটি সুপার () প্রয়োগের জন্য:

class First(object):
  def __init__(self):
    super(First, self).__init__()
    print "first"

class Second(object):
  def __init__(self):
    super(Second, self).__init__()
    print "second"

class Third(First, Second):
  def __init__(self):
    super(Third, self).__init__()
    print "that's it"

এটি কীভাবে এই পদ্ধতির সমাধান হবে তা স্পষ্ট হয়ে যায়

Third.__init__() ---> First.__init__() ---> Second.__init__() ---> 
Object.__init__() ---> returns ---> Second.__init__() -
prints "second" - returns ---> First.__init__() -
prints "first" - returns ---> Third.__init__() - prints "that's it"

"বরং এটি কারণ দ্বিতীয়টি একটি মাথা অবস্থানে উপস্থিত হয় এবং শ্রেনীর সাবসেটে লেজের অবস্থানে উপস্থিত হয় না।" এটি মাথা বা লেজের অবস্থান কী, বা শ্রেণিবদ্ধ সাবসেটটি কী বা আপনি কোন উপসেটটি উল্লেখ করছেন তা পরিষ্কার নয়।
অরেঞ্জ শরবেট

লেজ অবস্থান শ্রেণি শ্রেণিবিন্যাসের উচ্চতর এবং বিপরীতে যে ক্লাসগুলি বোঝায়। বেস শ্রেণীর 'অবজেক্ট' লেজের শেষে থাকে। ম্রো অ্যালগরিদম বোঝার মূল কীটি 'দ্বিতীয়' কীভাবে 'প্রথম' এর সুপার হিসাবে উপস্থিত হয়। আমরা সাধারণত এটি 'অবজেক্ট' শ্রেণি হিসাবে ধরে নিই। এটি সত্য, তবে কেবল 'প্রথম' শ্রেণীর দৃষ্টিকোণে। তবে 'তৃতীয়' শ্রেণির দৃষ্টিকোণ থেকে যখন দেখানো হয়, 'প্রথম' এর জন্য শ্রেণিবিন্যাসের ক্রমটি পৃথক এবং উপরে প্রদর্শিত হিসাবে গণনা করা হয়। এমআরও অ্যালগরিদম সমস্ত একাধিক উত্তরাধিকারী শ্রেণীর জন্য এই দৃষ্টিভঙ্গি (বা শ্রেণিবদ্ধ সাবসেট) তৈরি করার চেষ্টা করে
সুপি

3

অজগর 3.5+ উত্তরাধিকার অনুমানযোগ্য এবং আমার জন্য খুব সুন্দর দেখায়। দয়া করে এই কোডটি দেখুন:

class Base(object):
  def foo(self):
    print("    Base(): entering")
    print("    Base(): exiting")


class First(Base):
  def foo(self):
    print("   First(): entering Will call Second now")
    super().foo()
    print("   First(): exiting")


class Second(Base):
  def foo(self):
    print("  Second(): entering")
    super().foo()
    print("  Second(): exiting")


class Third(First, Second):
  def foo(self):
    print(" Third(): entering")
    super().foo()
    print(" Third(): exiting")


class Fourth(Third):
  def foo(self):
    print("Fourth(): entering")
    super().foo()
    print("Fourth(): exiting")

Fourth().foo()
print(Fourth.__mro__)

আউটপুট:

Fourth(): entering
 Third(): entering
   First(): entering Will call Second now
  Second(): entering
    Base(): entering
    Base(): exiting
  Second(): exiting
   First(): exiting
 Third(): exiting
Fourth(): exiting
(<class '__main__.Fourth'>, <class '__main__.Third'>, <class '__main__.First'>, <class '__main__.Second'>, <class '__main__.Base'>, <class 'object'>)

আপনি দেখতে পাচ্ছেন, এটি উত্তরাধিকার সূত্রে প্রাপ্ত প্রতিটি ক্রম হিসাবে একই ক্রমে প্রতিটি উত্তরাধিকারসূত্রে শৃঙ্খলার জন্য ঠিক একবারে ফুটিকে কল করে। আপনি কল করে এই আদেশ পেতে পারেন ম্রো :

চতুর্থ -> তৃতীয় -> প্রথম -> দ্বিতীয় -> বেস -> অবজেক্ট


2

সম্ভবত এখনও কিছু যুক্ত করা যেতে পারে, জ্যাঙ্গো রেস্ট_ফ্রেমওয়ার্ক এবং সজ্জকারগুলির সাথে একটি ছোট উদাহরণ। এটি অন্তর্ভুক্ত প্রশ্নের উত্তর সরবরাহ করে: "কেন আমি যাইহোক এটি চাইব?"

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

এখন পোষ্ট, পুট এবং মুছে ফেলুন আমরা জ্যাঙ্গোর লগইন_প্রযুক্তি দিয়ে সজ্জিত করতে চাই। লক্ষ্য করুন এটি কীভাবে উভয় শ্রেণিকে স্পর্শ করে তবে কোনও শ্রেণির সমস্ত পদ্ধতি নয়।

একটি সমাধান একাধিক উত্তরাধিকার মাধ্যমে যেতে পারে।

from django.utils.decorators import method_decorator
from django.contrib.auth.decorators import login_required

class LoginToPost:
    @method_decorator(login_required)
    def post(self, arg, *args, **kwargs):
        super().post(arg, *args, **kwargs)

একইভাবে অন্যান্য পদ্ধতির জন্য।

আমার কংক্রিট ক্লাসগুলির উত্তরাধিকার তালিকায় আমি LoginToPostআগে ListCreateAPIViewএবং LoginToPutOrDeleteআগে আমার যুক্ত করব RetrieveUpdateDestroyAPIView। আমার কংক্রিট ক্লাস ' getঅদক্ষিত থাকবে।


1

আমার ভবিষ্যতের রেফারেন্সের জন্য এই উত্তরটি পোস্ট করা।

পাইথন একাধিক উত্তরাধিকার হীরা মডেল ব্যবহার করা উচিত এবং ফাংশনের স্বাক্ষরটি মডেলটিতে পরিবর্তন হওয়া উচিত নয়।

    A
   / \
  B   C
   \ /
    D

নমুনা কোড স্নিপেট হবে; -

class A:
    def __init__(self, name=None):
        #  this is the head of the diamond, no need to call super() here
        self.name = name

class B(A):
    def __init__(self, param1='hello', **kwargs):
        super().__init__(**kwargs)
        self.param1 = param1

class C(A):
    def __init__(self, param2='bye', **kwargs):
        super().__init__(**kwargs)
        self.param2 = param2

class D(B, C):
    def __init__(self, works='fine', **kwargs):
        super().__init__(**kwargs)
        print(f"{works=}, {self.param1=}, {self.param2=}, {self.name=}")

d = D(name='Testing')

এখানে ক্লাস এ object


1
Aউচিত এছাড়াও কলিং হতে __init__Aপদ্ধতিটি "আবিষ্কার" করেন নি __init__, সুতরাং এটি ধরে নিতে পারে না যে এর Aআগে এমআরওতে অন্য কোনও শ্রেণি থাকতে পারে । শুধুমাত্র বর্গ যার __init__পদ্ধতি না (এবং উচিত নয়) কল super().__init__করা হয় object
চিপনার

হ্যাঁ। এজন্য আমি এ লিখেছি objectসম্ভবত আমি মনে করি, class A (object) : পরিবর্তে আমার লেখা উচিত
আখিল নাধ পিসি

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