পাইথনে ক্লাস পদ্ধতির পার্থক্য: আবদ্ধ, আনবাউন্ড এবং স্ট্যাটিক


242

নিম্নলিখিত শ্রেণীর পদ্ধতির মধ্যে পার্থক্য কী?

এটি একটি স্থির এবং অন্যটি না?

class Test(object):
  def method_one(self):
    print "Called method_one"

  def method_two():
    print "Called method_two"

a_test = Test()
a_test.method_one()
a_test.method_two()

18
মেথড_টুই () সংজ্ঞা ব্যতীত অন্য কোনও পার্থক্য অবৈধ এবং এর কল ব্যর্থ হয়।
এনাটোলি টেকটোনিক

14
@ টেকটোনিক: পদ্ধতির_ সংজ্ঞা দিয়ে কিছুই ভুল হয় না! এটি একটি ভুল / অবৈধ বর্ণনায় ডাকা হচ্ছে, অর্থাত্ অতিরিক্ত যুক্তি সহ।
0xc0de

1
আপনার উভয়ই ক্লাসের পদ্ধতি নয়, উদাহরণস্বরূপ পদ্ধতি। আপনি সংজ্ঞা প্রয়োগ করে একটি শ্রেণি পদ্ধতি তৈরি @classmethodকরেন। clsপরিবর্তে প্রথম প্যারামিটারটি কল করা উচিত selfএবং এটি আপনার শ্রেণীর উদাহরণ না দিয়ে ক্লাস অবজেক্টটি গ্রহণ করবে: Test.method_three()এবং a_test.method_three()এটি সমতুল্য।
লুৎজ প্রেশেল্ট

আপনি selfযুক্তি ছাড়াই কেন কোনও ফাংশন সংজ্ঞা তৈরি করতে চান ? এর জন্য কি শক্তিশালী ব্যবহারের মামলা রয়েছে?
alpha_989

উত্তর:


412

পাইথনে, আবদ্ধ এবং আনবাউন্ড পদ্ধতির মধ্যে পার্থক্য রয়েছে ।

মূলত, একটি সদস্য ফাংশনে কল (যেমন method_one), একটি সীমাবদ্ধ ফাংশন

a_test.method_one()

অনুবাদ করা হয়

Test.method_one(a_test)

একটি আনবাউন্ড পদ্ধতিতে একটি কল। যে কারণে আপনার সংস্করণে একটি কল সাথে method_twoব্যর্থ হবেTypeError

>>> a_test = Test() 
>>> a_test.method_two()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: method_two() takes no arguments (1 given) 

আপনি ডিকোরেটর ব্যবহার করে কোনও পদ্ধতির আচরণ পরিবর্তন করতে পারেন

class Test(object):
    def method_one(self):
        print "Called method_one"

    @staticmethod
    def method_two():
        print "Called method two"

সাজসজ্জাটি বিল্ট-ইন ডিফল্ট মেটাগ্লাসকে type(একটি শ্রেণির শ্রেণি, সিএফ। এই প্রশ্ন ) এর জন্য আবদ্ধ পদ্ধতি তৈরি না করতে বলে method_two

এখন, আপনি স্ট্যাটিক পদ্ধতিতে উদাহরণস্বরূপ বা ক্লাস উভয়ই সরাসরি প্রার্থনা করতে পারেন:

>>> a_test = Test()
>>> a_test.method_one()
Called method_one
>>> a_test.method_two()
Called method_two
>>> Test.method_two()
Called method_two

17
আমি এই উত্তরটি সমর্থন করি, এটি আমার চেয়ে শ্রেষ্ঠ। ভাল কাজ করেছে টর্স্টেন :)
ফ্রিস্পেস

24
পাইথনে 3 আনবাউন্ড পদ্ধতি হ্রাস করা হয়। পরিবর্তে কেবল একটি ফাংশন আছে।
সাহসী

@ বোলডনিক, আপনি কেন বলছেন যে আনবাউন্ড পদ্ধতি হ্রাস করা হয়? স্থির পদ্ধতিগুলি এখনও ডকুমেন্টেশনে উপস্থিত রয়েছে: docs.python.org/3/library/funitions.html#staticmethod
alpha_989

195

বর্ণনাকারী সিস্টেমের বেসিকগুলি বুঝতে পারলে পাইথনের পদ্ধতিগুলি খুব খুব সহজ জিনিস। নিম্নলিখিত শ্রেণীর কল্পনা করুন:

class C(object):
    def foo(self):
        pass

এবার শেলটিতে সেই ক্লাসটি একবার দেখে নেওয়া যাক:

>>> C.foo
<unbound method C.foo>
>>> C.__dict__['foo']
<function foo at 0x17d05b0>

আপনি দেখতে পাচ্ছেন fooযে ক্লাসের অ্যাট্রিবিউটটি অ্যাক্সেস করেন কিনা আপনি একটি আনবাউন্ড পদ্ধতি ফিরে পাবেন তবে ক্লাস স্টোরেজ (ডিক) এর ভিতরে একটি ফাংশন রয়েছে। এটা কেন? এর কারণ হ'ল আপনার শ্রেণীর শ্রেণি __getattribute__বর্ণনাকারীদের সমাধান করে এমন একটি প্রয়োগ করে । জটিল মনে হচ্ছে, তবে তা নয়। C.fooএই বিশেষ ক্ষেত্রে এই কোডটির সমতুল্য সমান:

>>> C.__dict__['foo'].__get__(None, C)
<unbound method C.foo>

কারণ ফাংশনগুলির একটি __get__পদ্ধতি রয়েছে যা তাদের বর্ণনাকারী করে। আপনার কাছে যদি কোনও ক্লাসের উদাহরণ থাকে তবে এটি প্রায় একই, Noneশ্রেণীর উদাহরণটি:

>>> c = C()
>>> C.__dict__['foo'].__get__(c, C)
<bound method C.foo of <__main__.C object at 0x17bd4d0>>

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

 class C(object):
  @staticmethod
  def foo():
   pass

staticmethodপ্রসাধক আপনার বর্গ এবং কার্যকরী একটি ডামি গোপন __get__ফাংশন হিসাবে আবৃত ফাংশনটি এবং একটি পদ্ধতি হিসাবে না যে:

>>> C.__dict__['foo'].__get__(None, C)
<function foo at 0x17d0c30>

আশা করি এটি ব্যাখ্যা করে।


12
staticmethodপ্রসাধক গোপন আপনার বর্গ (...) এই শব্দগুচ্ছ একটি বিট বর্গ যা আবৃত হচ্ছে বিভ্রান্তিকর বর্গ হয় এর পদ্ধতি fooএবং বর্গ যা fooসংজ্ঞায়িত করা হয়।
পাইওটর ডব্রোগোস্ট

12

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

এটি কার্যকরভাবে তৈরি করতে আপনি এটি আপনার শ্রেণির সংজ্ঞায় যুক্ত করতে পারেন:

method_two = staticmethod(method_two)

অথবা আপনি @staticmethod ফাংশন ডেকোরেটর ব্যবহার করতে পারেন ।


4
আপনার অর্থ "@staticmethod ফাংশন সাজসজ্জা সিনট্যাক্স"।
tzot

11
>>> class Class(object):
...     def __init__(self):
...         self.i = 0
...     def instance_method(self):
...         self.i += 1
...         print self.i
...     c = 0
...     @classmethod
...     def class_method(cls):
...         cls.c += 1
...         print cls.c
...     @staticmethod
...     def static_method(s):
...         s += 1
...         print s
... 
>>> a = Class()
>>> a.class_method()
1
>>> Class.class_method()    # The class shares this value across instances
2
>>> a.instance_method()
1
>>> Class.instance_method() # The class cannot use an instance method
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unbound method instance_method() must be called with Class instance as first argument (got nothing instead)
>>> Class.instance_method(a)
2
>>> b = 0
>>> a.static_method(b)
1
>>> a.static_method(a.c) # Static method does not have direct access to 
>>>                      # class or instance properties.
3
>>> Class.c        # a.c above was passed by value and not by reference.
2
>>> a.c
2
>>> a.c = 5        # The connection between the instance
>>> Class.c        # and its class is weak as seen here.
2
>>> Class.class_method()
3
>>> a.c
5

2
Class.instance_method() # The class cannot use an instance methodএটি ব্যবহার করতে পারেন। কেবল ম্যানুয়ালি উদাহরণটি পাস করুন:Class.instance_method(a)
ওয়ারওয়ারিয়াক

@warwaruk এটি আছে, লাইনের নীচের TyeErrorলাইনটি দেখুন।
kzh

হ্যাঁ আমি এটি পরে দেখেছি তবুও, যদিও, 'শ্রেণি কোনও উদাহরণ পদ্ধতি ব্যবহার করতে পারে না' বলা ঠিক নয়, কারণ আপনি এটি নীচে কেবল একটি লাইন করেছেন।
ওয়ারওয়ারিচ

@ কেজেড, আপনার ব্যাখ্যার জন্য ধন্যবাদ আপনি যখন ডেকেছিলেন a.class_method(), এটি a.cআপডেট হয়েছে বলে মনে হয় 1, সুতরাং কলটি কলটি পরিবর্তনশীলটিকে Class.class_method()আপডেট করে । যাইহোক, আপনি যখন নিয়োগ , কেন আপডেট করা হয়নি ? Class.c2a.c=5Class.c5
alpha_989

@ alpha_989 পাইথন প্রথমে প্রথমে একটি ডিম্বাশয়ের নিজস্ব উদাহরণে সরাসরি কোনও বৈশিষ্ট্যের সন্ধান করে এবং যদি এটি না থাকে তবে এটি ডিফল্টরূপে তার শ্রেণিতে এটি সন্ধান করে। আপনার যদি এই সম্পর্কে অন্য কোনও প্রশ্ন থাকে তবে দয়া করে বিনা দ্বিধায় একটি প্রশ্ন খুলুন এবং এটি এখানে লিঙ্ক করুন এবং আমি আরও সাহায্য করতে পেরে খুশি হব।
KZ

4

মেথড_টি দু'টি কাজ করবে না কারণ আপনি কোনও সদস্য ফাংশনটি সংজ্ঞায়িত করছেন তবে ফাংশনটি কীসের সদস্য তা তা বলছেন না। আপনি যদি শেষ লাইনটি কার্যকর করেন তবে আপনি পাবেন:

>>> a_test.method_two()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: method_two() takes no arguments (1 given)

আপনি যদি শ্রেণীর জন্য সদস্য ফাংশনগুলি সংজ্ঞায়িত করেন তবে প্রথম যুক্তি সর্বদা 'স্ব' হওয়া উচিত।


3

উপরের আরমিন রোনাচারের সঠিক ব্যাখ্যা, তার উত্তরগুলি প্রসারিত করে যাতে আমার মতো নতুনরা এটি ভাল বুঝতে পারে:

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

class C:
    a = [] 
    def foo(self):
        pass

C # this is the class object
C.a # is a list object (class property object)
C.foo # is a function object (class property object)
c = C() 
c # this is the class instance

__dict__বর্গ বস্তুর অভিধান সম্পত্তি সব বৈশিষ্ট্য এবং একটি বর্গ বস্তুর পদ্ধতি এবং এইভাবে রেফারেন্স ঝুলিতে

>>> C.__dict__['foo']
<function foo at 0x17d05b0>

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

যদি কোনও সিপিও বর্ণনাকারী হয়, তবে পাইথন ব্যাখ্যামূলক __get__()সিপিওর মধ্যে থাকা মানটি অ্যাক্সেস করার পদ্ধতিটিকে কল করে ।

সিপিও কোনও বর্ণনাকারী কিনা তা নির্ধারণ করার জন্য, পাইথন ব্যাখ্যাকারী এটি বিবরণকারী প্রোটোকল প্রয়োগ করে কিনা তা পরীক্ষা করে। বর্ণনাকারী প্রোটোকল বাস্তবায়নের জন্য 3 টি পদ্ধতি প্রয়োগ করা হয়

def __get__(self, instance, owner)
def __set__(self, instance, value)
def __delete__(self, instance)

যেমন

>>> C.__dict__['foo'].__get__(c, C)

কোথায়

  • self সিপিও (এটি তালিকার উদাহরণ, স্ট্রিং, ফাংশন ইত্যাদি হতে পারে) এবং রানটাইম দ্বারা সরবরাহ করা হয়
  • instance শ্রেণীর উদাহরণ যেখানে এই সিপিও সংজ্ঞায়িত করা হয়েছে (উপরে বস্তু 'গ') এবং আমাদের দ্বারা সরবরাহ করা প্রয়োজন
  • ownerএই সিপিওটি এমন ক্লাস যেখানে সংজ্ঞায়িত করা হয়েছে (উপরের শ্রেণি অবজেক্ট 'সি') এবং আমাদের সরবরাহ করতে হবে। তবে এটি কারণ এটি আমরা সিপিওতে কল করছি on যখন আমরা উদাহরণটিতে এটি কল করি তখন আমাদের এটি সরবরাহ করতে হবে না কারণ রানটাইম উদাহরণ বা তার শ্রেণি সরবরাহ করতে পারে (বহুবিজ্ঞান)
  • value সিপিওর জন্য উদ্দিষ্ট মান এবং এটি আমাদের সরবরাহ করতে হবে

সমস্ত সিপিও বর্ণনাকারী নয়। উদাহরণ স্বরূপ

>>> C.__dict__['foo'].__get__(None, C)
<function C.foo at 0x10a72f510> 
>>> C.__dict__['a'].__get__(None, C)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'list' object has no attribute '__get__'

এটি কারণ শ্রেণি বিবরণকারী প্রোটোকলটি কার্যকর করে না।

সুতরাং নিজের মধ্যে যুক্তিটি c.foo(self)প্রয়োজনীয় কারণ এটির পদ্ধতি স্বাক্ষরটি আসলে এটিC.__dict__['foo'].__get__(c, C) (উপরে বর্ণিত হিসাবে সি এর প্রয়োজন নেই কারণ এটি খুঁজে পাওয়া যায় বা বহুগুণিত হয়) এবং এটি প্রয়োজনীয় কারণের যুক্তিটি পাস না করে আপনি যদি টাইপররও পান তবে এটিও।

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

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

class C(object):
  @staticmethod
  def foo():
   pass

নতুন মোড়ানো সিপিওতে প্রসঙ্গের অনুপস্থিতি fooত্রুটি ঘটায় না এবং নীচে যাচাই করা যেতে পারে:

>>> C.__dict__['foo'].__get__(None, C)
<function foo at 0x17d0c30>

স্ট্যাটিক পদ্ধতির ব্যবহারের ক্ষেত্রে নেমস্পেসিং এবং কোড রক্ষণাবেক্ষণযোগ্যতা (এটি কোনও শ্রেণীর বাইরে নিয়ে যাওয়া এবং মডিউল জুড়ে এটি উপলব্ধ করা ইত্যাদি) is

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


1

এটি একটি ত্রুটি।

প্রথমত, প্রথম লাইনটি এর মতো হওয়া উচিত (রাজধানী সম্পর্কে সতর্ক থাকুন)

class Test(object):

আপনি যখনই কোনও ক্লাসের কোনও পদ্ধতিকে কল করেন তখন এটি নিজেকে প্রথম যুক্তি হিসাবে মনে হয় (অতএব নামটি স্বতঃ) এবং পদ্ধতি_এই ত্রুটি দেয়

>>> a.method_two()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: method_two() takes no arguments (1 given)

1

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


যদি আমি কোনও ফাংশন Class Test(object): @staticmethod def method_two(): print(“called method_two”) ওয়ান ইউজ কেসটিকে সংজ্ঞায়িত করি , তখন আমি ভাবছিলাম যখন আপনি ফাংশনটি কোনও শ্রেণীর অংশ হতে চান তবে ব্যবহারকারীটি সরাসরি ফাংশনটি অ্যাক্সেস করতে চান না। সুতরাং উদাহরণটি method_twoঅন্য ফাংশন দ্বারা কল করা যেতে পারে Test, কিন্তু ক্যান্ট ব্যবহার করে বলা যেতে পারে a_test.method_two()। যদি আমি ব্যবহার করি তবে এটি def method_two()কি এই ব্যবহারের ক্ষেত্রে কাজ করবে? বা ফাংশন সংজ্ঞাটি সংশোধন করার আরও ভাল উপায় আছে, সুতরাং এটি উপরের ব্যবহারের ক্ষেত্রে হিসাবে কাজ করে?
alpha_989

1

মেথড_টায় কলটি পাইথন রানটাইমটি স্বয়ংক্রিয়ভাবে এটি পাস করবে এমন স্ব প্যারামিটার গ্রহণ না করার জন্য একটি ব্যতিক্রম ছুঁড়ে দেবে।

আপনি যদি পাইথন ক্লাসে একটি স্ট্যাটিক পদ্ধতি তৈরি করতে চান তবে এটি দিয়ে সজ্জিত করুন staticmethod decorator

Class Test(Object):
  @staticmethod
  def method_two():
    print "Called method_two"

Test.method_two()


0

সংজ্ঞাটি method_twoঅবৈধ। আপনি যখন ফোন করবেন method_two, আপনি TypeError: method_two() takes 0 positional arguments but 1 was givenদোভাষী থেকে পাবেন ।

যখন আপনি এটি পছন্দ করেন তখন একটি উদাহরণ পদ্ধতি একটি সীমাবদ্ধ ফাংশন a_test.method_two()। এটি স্বয়ংক্রিয়ভাবে গ্রহণ করে self, যা Testএটির প্রথম পরামিতি হিসাবে কোনও উদাহরণকে নির্দেশ করে । selfপ্যারামিটারের মাধ্যমে , একটি উদাহরণ পদ্ধতি অবাধে অ্যাট্রিবিউটগুলি অ্যাক্সেস করতে এবং একই বস্তুতে সেগুলি সংশোধন করতে পারে।


0

আনবাউন্ড পদ্ধতি

আনবাউন্ড পদ্ধতিগুলি এমন পদ্ধতি যা এখনও কোনও নির্দিষ্ট শ্রেণীর উদাহরণের সাথে আবদ্ধ নয়।

বাউন্ড পদ্ধতি

বাউন্ড পদ্ধতিগুলি একটি শ্রেণীর নির্দিষ্ট উদাহরণে আবদ্ধ।

তার নথিভুক্ত হিসাবে এখানে , স্ব ফাংশন উপর নির্ভর করে, আবদ্ধ হয় আনবাউন্ড বা স্ট্যাটিক বিভিন্ন জিনিস পাঠাতে পারেন।

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

class MyClass:    
    def some_method(self):
        return self  # For the sake of the example

>>> MyClass().some_method()
<__main__.MyClass object at 0x10e8e43a0># This can also be written as:>>> obj = MyClass()

>>> obj.some_method()
<__main__.MyClass object at 0x10ea12bb0>

# Bound method call:
>>> obj.some_method(10)
TypeError: some_method() takes 1 positional argument but 2 were given

# WHY IT DIDN'T WORK?
# obj.some_method(10) bound call translated as
# MyClass.some_method(obj, 10) unbound method and it takes 2 
# arguments now instead of 1 

# ----- USING THE UNBOUND METHOD ------
>>> MyClass.some_method(10)
10

যেহেতু আমরা ক্লাসের উদাহরণটি ব্যবহার করি নি - obj - শেষ কলে, আমরা দয়া করে বলতে পারি এটি দেখতে একটি স্থির পদ্ধতির মতো।

যদি তাই হয়, MyClass.some_method(10)একটি দ্বারা সজ্জিত স্ট্যাটিক ফাংশনে কল এবং কলের মধ্যে পার্থক্য কী@staticmethod ?

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

এছাড়াও, @staticmethodসাজসজ্জা যুক্ত করে , আমরা এটি কোনও বস্তুর মাধ্যমেও পৌঁছানো সম্ভব করে তুলছি।

class MyClass:    
    def some_method(self):
        return self    

    @staticmethod
    def some_static_method(number):
        return number

>>> MyClass.some_static_method(10)   # without an instance
10
>>> MyClass().some_static_method(10)   # Calling through an instance
10

আপনি উদাহরণ পদ্ধতিগুলি সহ উপরের উদাহরণটি করতে পারবেন না। আপনি প্রথমটি বেঁচে থাকতে পারেন (যেমনটি আমরা আগে করেছি) তবে দ্বিতীয়টি একটি আনবাউন্ড কলটিতে অনুবাদ করা MyClass.some_method(obj, 10)হবে যা একটি উত্থাপন করবেTypeError যেহেতু উদাহরণ পদ্ধতিটি একটি যুক্তি নেয় এবং আপনি অজান্তেই দুটি পাস করার চেষ্টা করেছিলেন।

তারপরে, আপনি বলতে পারেন, "আমি যদি উদাহরণ এবং ক্লাস উভয়ের মাধ্যমে স্থিতিশীল পদ্ধতিগুলি কল করতে পারি MyClass.some_static_methodএবং MyClass().some_static_methodএকই পদ্ধতি হওয়া উচিত” " হ্যাঁ!


0

গণ্ডি পদ্ধতি = উদাহরণ পদ্ধতি

আনবাউন্ড পদ্ধতি = স্থির পদ্ধতি।


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