আমি কখন ক্লাসমেডোথার এবং কখন ডিএফ পদ্ধতি (স্ব) ব্যবহার করব?


92

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

class Dummy(object):

    def some_function(self,*args,**kwargs):
        do something here
        self is the class instance

অন্যটি হ'ল আমি ব্যবহার করি না, কারণ এটি কখন ব্যবহার করব তা আমি বুঝতে পারি না এবং এর জন্য:

class Dummy(object):

    @classmethod
    def some_function(cls,*args,**kwargs):
        do something here
        cls refers to what?

পাইথন ডক্সে classmethodসাজসজ্জারকে এই বাক্যটি দিয়ে ব্যাখ্যা করা হয়:

কোনও শ্রেণি পদ্ধতি যেমন প্রথম উদাহরণ হিসাবে উদাহরণটি গ্রহণ করে ঠিক তেমন প্রথম যুক্তি হিসাবে ক্লাস গ্রহণ করে receives

সুতরাং আমি অনুমান করি নিজেকে clsবোঝায় Dummy( classউদাহরণটি নয়)। এটি কেন বিদ্যমান তা আমি ঠিক বুঝতে পারি না, কারণ আমি সবসময় এটি করতে পারি:

type(self).do_something_with_the_class

এটি কি কেবল স্বচ্ছতার স্বার্থে, বা আমি সবচেয়ে গুরুত্বপূর্ণ অংশটি মিস করেছি: ভুতুড়ে এবং আকর্ষণীয় জিনিসগুলি ছাড়া এটি করা যায় না?

উত্তর:


71

আপনার অনুমান সঠিক - আপনি কীভাবে classmethod কাজ করে তা বুঝতে পারেন

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

class Dummy(object):

    @classmethod
    def some_function(cls,*args,**kwargs):
        print cls

#both of these will have exactly the same effect
Dummy.some_function()
Dummy().some_function()

উদাহরণস্বরূপ এগুলির ব্যবহার সম্পর্কে : উদাহরণস্বরূপ শ্রেণীবদ্ধকে ফোন করার জন্য কমপক্ষে দুটি প্রধান ব্যবহার রয়েছে:

  1. self.some_function()যে শ্রেণিতে সেই কলটি প্রদর্শিত হবে তার পরিবর্তে some_functionপ্রকৃত ধরণের সংস্করণটি কল করবে self(এবং শ্রেণীর নামকরণ করা হলে মনোযোগ দেওয়ার প্রয়োজন হবে না); এবং
  2. some_functionকিছু প্রোটোকল বাস্তবায়ন করা প্রয়োজন ক্ষেত্রে , তবে একা ক্লাস অবজেক্টে কল করা কার্যকর।

এর সাথে পার্থক্যstaticmethod : পদ্ধতিগুলি সংজ্ঞায়নের আরও একটি উপায় রয়েছে যা দৃষ্টান্তের ডেটা অ্যাক্সেস করে না staticmethod। এটি এমন একটি পদ্ধতি তৈরি করে যা প্রথমে অন্তর্নিহিত প্রথম যুক্তি পায় না; সেই অনুসারে এটি যে উদাহরণ বা শ্রেণীর উপর ডাকা হয়েছিল সে সম্পর্কে কোনও তথ্য দেওয়া হবে না।

In [6]: class Foo(object): some_static = staticmethod(lambda x: x+1)

In [7]: Foo.some_static(1)
Out[7]: 2

In [8]: Foo().some_static(1)
Out[8]: 2

In [9]: class Bar(Foo): some_static = staticmethod(lambda x: x*2)

In [10]: Bar.some_static(1)
Out[10]: 2

In [11]: Bar().some_static(1)
Out[11]: 2

এটির জন্য আমি যে প্রধান ব্যবহারটি পেয়েছি তা হ'ল selfএকটি ক্লাসে (বা অবজেক্ট) পদ্ধতিতে কোনও বিদ্যমান ফাংশনটি (যা প্রাপ্তির প্রত্যাশা করে না ) অভিযোজিত ।


4
চমৎকার একটি: আমি উত্তরটি কীভাবে - কেন বিভক্ত হওয়া পছন্দ করি। যতদূর আমি এটি পেয়েছি @ ক্লাসমেডোড কোনও উদাহরণের প্রয়োজন ছাড়াই ফাংশনটি অ্যাক্সেস করার অনুমতি দেয়। আমি ঠিক তাই খুঁজছিলাম, আপনাকে ধন্যবাদ।
marue

4
@ মার্সিন ট্রু হাঁসের টাইপিং এটিকে আরও কিছু মাত্রা দেয়। এটি self.foo()কখন লেখা উচিত নয় এমন বিষয়গুলি লেখার বিষয়ে নয় Bar.foo()
ভু

4
@ ভু আসলে, self.foo()পছন্দনীয়, কারণ selfএটি একটি সাবক্লাসের একটি উদাহরণ হতে পারে যা এটির নিজের প্রয়োগ করে foo
মার্সিন

4
@ মার্সিন আমি মনে করি এটি আপনি কী অর্জন করতে চান তার উপর নির্ভর করে। তবে আমি আপনার বক্তব্য পেতে।
marue

4
আপনার জন্য একটি ভিন্ন ল্যামডা ব্যবহার করা উচিত Bar, যেমন 1+1 == 2 == 1*2, তাই এটি দেখানো ফলাফল থেকে বলতে অসম্ভব Bar().static_methodআসলে বলা হয়।
জর্জ ভি। রিলি

0

মূলত, যখন আপনি বুঝতে পারবেন যে পদ্ধতির সংজ্ঞাটি পরিবর্তন করা হবে না বা ওভাররাইড করা হবে না তখন আপনার একটি @ ক্লাসমেডো ব্যবহার করা উচিত।

একটি অতিরিক্ত: teorically, বর্গ পদ্ধতি দ্রুত হয় তবে অবজেক্ট পদ্ধতি, কারণ তাত্ক্ষণিক হওয়া প্রয়োজন হয় না এবং কম মেমরির প্রয়োজন হয় না।


-3

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

class TestMethod(object):
    cls_var = 1
    @classmethod
    def class_method(cls):
        cls.cls_var += 1
        print cls.cls_var

    @staticmethod
    def static_method():
        TestMethod.cls_var += 1
        print TestMethod.cls_var
#call each method from class itself.
TestMethod.class_method()
TestMethod.static_method()

#construct instances
testMethodInst1 = TestMethod()    
testMethodInst2 = TestMethod()   

#call each method from instances
testMethodInst1.class_method()
testMethodInst2.static_method()

এই সমস্ত ক্লাসগুলি 1 দ্বারা cls.cls_var বাড়িয়ে মুদ্রণ করে।

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

এবং গুরুত্বপূর্ণ প্রশ্ন। কেন এই পদ্ধতির প্রয়োজন হবে।

ক্লাসমেডথ বা স্ট্যাটিকমেডোথ যখন আপনি সেই ক্লাসটিকে কারখানা হিসাবে তৈরি করেন বা যখন আপনার ক্লাসটি কেবল একবার শুরু করতে হয় তখন দরকারী। একবার ওপেন ফাইলের মতো, এবং ফিড পদ্ধতিটি ব্যবহার করে লাইনে ফাইল লাইন পড়তে হবে।


4
(ক) স্থির পদ্ধতি অন্যরকম কিছু; (খ) শ্রেণিবদ্ধ প্রত্যেক শ্রেণীর দ্বারা ভাগ করা হয় না।
মার্সিন

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