__getattribute__
পদ্ধতিটি কীভাবে ব্যবহৃত হয়?
এটি সাধারণ ডটেড লুকআপের আগে ডাকা হয়। যদি এটি উত্থাপিত হয় AttributeError
, তবে আমরা কল করি __getattr__
।
এই পদ্ধতির ব্যবহার বরং বিরল। স্ট্যান্ডার্ড লাইব্রেরিতে কেবল দুটি সংজ্ঞা রয়েছে:
$ grep -Erl "def __getattribute__\(self" cpython/Lib | grep -v "/test/"
cpython/Lib/_threading_local.py
cpython/Lib/importlib/util.py
ভাল অভ্যাস
প্রোগ্রামটিমেটিকভাবে একটি একক বৈশিষ্ট্যে অ্যাক্সেস নিয়ন্ত্রণের সঠিক উপায়টি রয়েছে property
। ক্লাসটি D
নিম্নরূপে লিখতে হবে (স্পষ্টতাত্ত্বিক আচরণের প্রতিলিপি তৈরির জন্য সেটার এবং মুছে ফেলার সাথে):
class D(object):
def __init__(self):
self.test2=21
@property
def test(self):
return 0.
@test.setter
def test(self, value):
'''dummy function to avoid AttributeError on setting property'''
@test.deleter
def test(self):
'''dummy function to avoid AttributeError on deleting property'''
এবং ব্যবহার:
>>> o = D()
>>> o.test
0.0
>>> o.test = 'foo'
>>> o.test
0.0
>>> del o.test
>>> o.test
0.0
একটি সম্পত্তি হ'ল ডেটা বর্ণনাকারী, সুতরাং সাধারণ বিন্দুযুক্ত লুকোচুরি অ্যালগরিদমে এটি প্রথম জিনিসটির সন্ধান করা হয়।
জন্য বিকল্প __getattribute__
আপনার একেবারে প্রতিটি অ্যাট্রিবিউটের মাধ্যমে অনুসন্ধানের বাস্তবায়ন করতে হবে যদি আপনি বেশ কয়েকটি বিকল্প __getattribute__
।
- উত্থাপন
AttributeError
, __getattr__
ডেকে আনা কারণ (যদি প্রয়োগ করা হয়)
- এটি থেকে কিছু ফিরে
super
পিতামাতাকে (সম্ভবত object
এর) বাস্তবায়ন কল করতে ব্যবহার করে
- কলিং
__getattr__
- আপনার নিজের বিন্দুযুক্ত অনুসন্ধানের অ্যালগরিদমটি কোনওভাবে বাস্তবায়ন করা হচ্ছে
উদাহরণ স্বরূপ:
class NoisyAttributes(object):
def __init__(self):
self.test=20
self.test2=21
def __getattribute__(self, name):
print('getting: ' + name)
try:
return super(NoisyAttributes, self).__getattribute__(name)
except AttributeError:
print('oh no, AttributeError caught and reraising')
raise
def __getattr__(self, name):
"""Called if __getattribute__ raises AttributeError"""
return 'close but no ' + name
>>> n = NoisyAttributes()
>>> nfoo = n.foo
getting: foo
oh no, AttributeError caught and reraising
>>> nfoo
'close but no foo'
>>> n.test
getting: test
20
আপনি মূলত যা চেয়েছিলেন
এবং এই উদাহরণটি দেখায় যে আপনি কী করতে পারেন মূলত:
class D(object):
def __init__(self):
self.test=20
self.test2=21
def __getattribute__(self,name):
if name=='test':
return 0.
else:
return super(D, self).__getattribute__(name)
এবং এইরকম আচরণ করবে:
>>> o = D()
>>> o.test = 'foo'
>>> o.test
0.0
>>> del o.test
>>> o.test
0.0
>>> del o.test
Traceback (most recent call last):
File "<pyshell#216>", line 1, in <module>
del o.test
AttributeError: test
কোড পূনর্বিবেচনা
মন্তব্য সহ আপনার কোড। আপনার নিজের মধ্যে বিন্দু চেহারা আছে __getattribute__
। এই কারণেই আপনি পুনরাবৃত্তি ত্রুটি পান। আপনি নামটি কিনা তা পরীক্ষা করে দেখতে পারেন "__dict__"
এবং এই ব্যবহারটি ব্যবহার super
করতে পারেন তবে এটি কভার করে না __slots__
। আমি পাঠকের কাছে অনুশীলন হিসাবে রেখে দেব।
class D(object):
def __init__(self):
self.test=20
self.test2=21
def __getattribute__(self,name):
if name=='test':
return 0.
else:
return self.__dict__[name]
>>> print D().test
0.0
>>> print D().test2
...
RuntimeError: maximum recursion depth exceeded in cmp