__getattribute__
যখনই কোনও অ্যাট্রিবিউট অ্যাক্সেস ঘটে তখন তাকে ডাকা হয়।
class Foo(object):
def __init__(self, a):
self.a = 1
def __getattribute__(self, attr):
try:
return self.__dict__[attr]
except KeyError:
return 'default'
f = Foo(1)
f.a
এটি অসীম পুনরাবৃত্তি ঘটায়। এখানে অপরাধী লাইন return self.__dict__[attr]
। আসুন ভান করা যাক (এটি সত্যের নিকটবর্তী) যে সমস্ত বৈশিষ্ট্যগুলি self.__dict__
তাদের নামে সঞ্চিত এবং উপলব্ধ। লাইন
f.a
এর a
বৈশিষ্ট্যটি অ্যাক্সেস করার চেষ্টা করে f
। এই কল f.__getattribute__('a')
। __getattribute__
তারপরে লোড করার চেষ্টা করে self.__dict__
। __dict__
একটি অ্যাট্রিবিউট self == f
এবং তাই পাইথন কলগুলি f.__getattribute__('__dict__')
আবার বৈশিষ্ট্যটি অ্যাক্সেস করার চেষ্টা করে '__dict__
। এটি অসীম পুনরাবৃত্তি।
__getattr__
পরিবর্তে যদি ব্যবহার করা হয়
- এটি কখনও চালিত হত না কারণ
f
একটি a
বৈশিষ্ট্য রয়েছে।
- যদি এটি চালানো হয়, (আসুন আমরা এটি জিজ্ঞাসা করি যে আপনি জিজ্ঞাসা করেছিলেন
f.b
) তবে এটি অনুসন্ধানের জন্য ডাকা হত না __dict__
কারণ এটি ইতিমধ্যে রয়েছে এবং __getattr__
কেবলমাত্র অনুরোধ করা হয়েছে যদি বৈশিষ্ট্যটি অনুসন্ধানের অন্যান্য সমস্ত পদ্ধতি ব্যর্থ হয় ।
'সঠিক' পথ ব্যবহার করে উপরে উল্লেখিত বর্গ লিখতে __getattribute__
হয়
class Foo(object):
# Same __init__
def __getattribute__(self, attr):
return super(Foo, self).__getattribute__(attr)
super(Foo, self).__getattribute__(attr)
__getattribute__
'নিকটতম' সুপারক্লাসের পদ্ধতিটি (আনুষ্ঠানিকভাবে, ক্লাসের মেথড রেজোলিউশন অর্ডারের পরবর্তী শ্রেণি, বা এমআরও) বর্তমান অবজেক্টের সাথে আবদ্ধ করে self
এবং পরে এটি কল করে এবং সেই কাজটি করতে দেয়।
এই সমস্ত সমস্যা এড়ানো এড়ানো যায় __getattr__
যা কোনও অ্যাট্রিবিউট সন্ধান না পাওয়া পর্যন্ত পাইথনটিকে এটি স্বাভাবিক জিনিস করতে দেয় । সেই সময়ে পাইথন আপনার __getattr__
পদ্ধতির উপর নিয়ন্ত্রণ রাখে এবং এটিকে কিছু দিয়ে আসে।
আপনি যে অসীম পুনরাবৃত্তি দিয়ে চালাতে পারেন তাও লক্ষণীয় __getattr__
।
class Foo(object):
def __getattr__(self, attr):
return self.attr
ওকে আমি এক্সারসাইজ হিসাবে ছেড়ে দেব।