উপরের আরমিন রোনাচারের সঠিক ব্যাখ্যা, তার উত্তরগুলি প্রসারিত করে যাতে আমার মতো নতুনরা এটি ভাল বুঝতে পারে:
স্থিতিশীল বা উদাহরণ পদ্ধতিতে (শ্রেণীর পদ্ধতি রয়েছে - এখানে আরও একটি ধরণের রয়েছে - শ্রেণি পদ্ধতি - এটি এড়াতে এখানে আলোচনা করা হয়নি), তারা কোনওভাবে শ্রেণীর উদাহরণের সাথে আবদ্ধ কিনা বা না তা এই সত্যটি চিহ্নিত করুন। উদাহরণস্বরূপ, বলুন যে রানটাইম চলাকালীন পদ্ধতিটি শ্রেণীর উদাহরণের জন্য একটি রেফারেন্স পেয়েছে কিনা
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
সম্ভবত যখনই সম্ভব পদ্ধতি উদাহরণগুলির চেয়ে স্থির পদ্ধতিগুলি লেখাই ভাল, যদি না আপনি অবশ্যই পদ্ধতিগুলি (যেমন অ্যাক্সেস ইনস্ট্যান্স ভেরিয়েবল, শ্রেণি ভেরিয়েবল ইত্যাদি) প্রাসঙ্গিক করা প্রয়োজন। একটি কারণ অবজেক্টগুলিতে অযাচিত রেফারেন্স না রেখে আবর্জনা সংগ্রহ সহজ করা।