আমি কখন __getattr__বা কখন ব্যবহার করব তা বোঝার চেষ্টা করছি __getattribute__। ডকুমেন্টেশন উল্লেখ __getattribute__নতুন স্টাইলের শ্রেণীর ক্ষেত্রে প্রযোজ্য। নতুন ধাঁচের ক্লাস কি?
আমি কখন __getattr__বা কখন ব্যবহার করব তা বোঝার চেষ্টা করছি __getattribute__। ডকুমেন্টেশন উল্লেখ __getattribute__নতুন স্টাইলের শ্রেণীর ক্ষেত্রে প্রযোজ্য। নতুন ধাঁচের ক্লাস কি?
উত্তর:
এর মধ্যে একটি মূল পার্থক্য __getattr__এবং __getattribute__যে __getattr__শুধুমাত্র যদি অ্যাট্রিবিউট স্বাভাবিক উপায়ে পাওয়া যায়নি প্রার্থনা করা হয়। অনুপস্থিত বৈশিষ্ট্যগুলির জন্য ফ্যালব্যাক বাস্তবায়নের জন্য এটি ভাল এবং সম্ভবত আপনি যে দুটিতে চান তার মধ্যে একটি এটি।
__getattribute__বস্তুর প্রকৃত বৈশিষ্ট্যগুলি দেখার আগে অনুরোধ করা হয়েছিল এবং তাই সঠিকভাবে প্রয়োগ করা জটিল trick আপনি খুব সহজেই অনন্ত পুনরাবৃত্তিতে শেষ করতে পারেন।
নতুন স্টাইলের ক্লাসগুলি থেকে প্রাপ্ত object, পুরাতন-শৈলীর ক্লাসগুলি পাইথন ২.x এর কোনও স্পষ্ট বেস ক্লাস নয়। কিন্তু পুরোনো শৈলী এবং নতুন স্টাইলের শ্রেণীর মধ্যে পার্থক্য গুরুত্বপূর্ণ যখন মধ্যবর্তী নির্বাচন নয় __getattr__এবং __getattribute__।
আপনি প্রায় অবশ্যই চান __getattr__।
__getattribute__প্রতিটি অ্যাক্সেসের জন্য ডাকা হবে, এবং __getattr__যে বার __getattribute__উত্থাপিত হয়েছিল তার জন্য ডাকা হবে AttributeError। শুধু কেন সব কিছু রাখবেন না?
__getattribute__।
objec.__getattribute__প্রার্থনা myclass.__getattr__।
উভয় __getattr__এবং __getattribute__যাদু পদ্ধতির কয়েকটি সাধারণ উদাহরণ দেখতে দিন ।
__getattr__পাইথন __getattr__যখনই এমন কোনও বৈশিষ্ট্যের জন্য অনুরোধ করবে যা ইতিমধ্যে সংজ্ঞায়িত করা হয়নি Py নিম্নলিখিত উদাহরণে আমার ক্লাস কাউন্টের কোনও __getattr__পদ্ধতি নেই। এখন প্রধানত যখন আমি উভয়টি অ্যাক্সেস করার চেষ্টা করি obj1.myminএবং obj1.mymaxবৈশিষ্ট্যগুলি সবকিছু ঠিকঠাক করে দেয়। তবে যখন আমি obj1.mycurrentঅ্যাট্রিবিউটটি অ্যাক্সেস করার চেষ্টা করি - পাইথন আমাকে দেয়AttributeError: 'Count' object has no attribute 'mycurrent'
class Count():
def __init__(self,mymin,mymax):
self.mymin=mymin
self.mymax=mymax
obj1 = Count(1,10)
print(obj1.mymin)
print(obj1.mymax)
print(obj1.mycurrent) --> AttributeError: 'Count' object has no attribute 'mycurrent'
এখন আমার ক্লাসের কাউন্ট হয়েছে __getattr__পদ্ধতি। এখন যখন আমি obj1.mycurrentঅ্যাট্রিবিউটটি অ্যাক্সেস করার চেষ্টা করি - পাইথন আমার __getattr__পদ্ধতিতে যা প্রয়োগ করেছি তা আমাকে ফিরিয়ে দেয় । আমার উদাহরণে আমি যখনই কোনও অ্যাট্রিবিউটকে কল করার চেষ্টা করি যা বিদ্যমান নেই, পাইথন সেই বৈশিষ্ট্যটি তৈরি করে এবং এটি পূর্ণসংখ্যার মান 0 তে সেট করে।
class Count:
def __init__(self,mymin,mymax):
self.mymin=mymin
self.mymax=mymax
def __getattr__(self, item):
self.__dict__[item]=0
return 0
obj1 = Count(1,10)
print(obj1.mymin)
print(obj1.mymax)
print(obj1.mycurrent1)
__getattribute__এখন __getattribute__পদ্ধতিটি দেখতে দিন see আপনি যদি __getattribute__আপনার বর্গ পদ্ধতি, পাইথন নির্বিশেষে প্রত্যেক অ্যাট্রিবিউট জন্য এই পদ্ধতি আবাহন করে ফাইলটার অস্তিত্ব তথা না। তাহলে আমাদের কেন __getattribute__পদ্ধতি দরকার ? একটি ভাল কারণ হ'ল আপনি নীচের উদাহরণে বর্ণিত বৈশিষ্ট্যগুলিতে অ্যাক্সেস আটকাতে এবং এটিকে আরও সুরক্ষিত করতে পারেন।
যখনই কেউ আমার অ্যাট্রিবিউটগুলি অ্যাক্সেস করার চেষ্টা করে যা 'কার' পাইথনটি সাবস্ট্রিং দিয়ে শুরু হয় তার AttributeErrorব্যতিক্রম উত্থাপন করে । অন্যথায় এটি যে বৈশিষ্ট্যটি ফেরত দেয়।
class Count:
def __init__(self,mymin,mymax):
self.mymin=mymin
self.mymax=mymax
self.current=None
def __getattribute__(self, item):
if item.startswith('cur'):
raise AttributeError
return object.__getattribute__(self,item)
# or you can use ---return super().__getattribute__(item)
obj1 = Count(1,10)
print(obj1.mymin)
print(obj1.mymax)
print(obj1.current)
গুরুত্বপূর্ণ: __getattribute__পদ্ধতিতে অসীম পুনরাবৃত্তি এড়ানোর জন্য , এর বাস্তবায়নের জন্য প্রয়োজনীয় বৈশিষ্ট্যগুলির অ্যাক্সেসের জন্য সর্বদা একই নামের সাথে বেস বর্গ পদ্ধতিটি কল করা উচিত। : উদাহরণস্বরূপ object.__getattribute__(self, name)বা super().__getattribute__(item)নাself.__dict__[item]
যদি আপনার শ্রেণিতে উভয়টি গ্যাটট্রা এবং গেট্যাট্রিবিট যাদু পদ্ধতি থাকে তবে __getattribute__প্রথমে তাকে বলা হয়। তবে যদি ব্যতিক্রম __getattribute__উত্থাপন করে
AttributeErrorতবে ব্যতিক্রম উপেক্ষা করা __getattr__হবে এবং পদ্ধতিটি চাওয়া হবে। নিম্নলিখিত উদাহরণটি দেখুন:
class Count(object):
def __init__(self,mymin,mymax):
self.mymin=mymin
self.mymax=mymax
self.current=None
def __getattr__(self, item):
self.__dict__[item]=0
return 0
def __getattribute__(self, item):
if item.startswith('cur'):
raise AttributeError
return object.__getattribute__(self,item)
# or you can use ---return super().__getattribute__(item)
# note this class subclass object
obj1 = Count(1,10)
print(obj1.mymin)
print(obj1.mymax)
print(obj1.current)
__getattribute__তবে অবশ্যই এটি নয়। কারণ আপনার উদাহরণ অনুসারে, আপনি যা করছেন __getattribute__তা AttributeErrorব্যতিক্রম বাড়াচ্ছে যদি অ্যাট্রিবিউটটির মধ্যে বৈশিষ্ট্যটি না থাকে __dict__; তবে আপনার সত্যিই __getattribute__এটির প্রয়োজন নেই কারণ এটি ডিফল্ট বাস্তবায়ন এবং __getattr__ফলব্যাক প্রক্রিয়া হিসাবে আপনার যা প্রয়োজন ঠিক তেমনই ।
currentদৃষ্টান্ত উপর সংজ্ঞায়িত করা হয় Count(দেখুন __init__), তাই কেবল উত্থাপন AttributeErrorঅ্যাট্রিবিউট সেখানে নেই হলে বেশ কি ঘটছে না - এটি অবকাশ __getattr__জন্য সব নাম 'বর্তমান' শুরু সহ current, কিন্তু curious, curly...
নেড ব্যাচেল্ডারের ব্যাখ্যার ভিত্তিতে এটি কেবল একটি উদাহরণ ।
__getattr__ উদাহরণ:
class Foo(object):
def __getattr__(self, attr):
print "looking up", attr
value = 42
self.__dict__[attr] = value
return value
f = Foo()
print f.x
#output >>> looking up x 42
f.x = 3
print f.x
#output >>> 3
print ('__getattr__ sets a default value if undefeined OR __getattr__ to define how to handle attributes that are not found')
এবং যদি একই উদাহরণ ব্যবহার করা হয় তবে __getattribute__আপনি >>> পাবেনRuntimeError: maximum recursion depth exceeded while calling a Python object
__getattr__()বাস্তবায়ন কেবল AttributeErrorঅবৈধ বৈশিষ্ট্য নামগুলির জন্য উত্থাপনের মাধ্যমে বৈধ বৈশিষ্ট্য নামের একটি সীমাবদ্ধ সেট গ্রহণ করে , যার ফলে সূক্ষ্ম এবং কঠিন থেকে ডিবাগ সমস্যাগুলি এড়ানো হয় । এই উদাহরণটি নিঃশর্তভাবে সমস্ত বৈশিষ্ট্যের নামকে বৈধ হিসাবে গ্রহণ করে - একটি উদ্ভট (এবং স্পষ্টতই ত্রুটি-প্রবণ) এর অপব্যবহার __getattr__()। আপনি যদি উদাহরণ হিসাবে যেমন গুণাবলী তৈরির উপরে "সম্পূর্ণ নিয়ন্ত্রণ" চান তবে আপনি তার __getattribute__()পরিবর্তে চান ।
defaultdict।
__getattr__ ডাকা হবে । এটি সরাসরি উপশ্রেণীর জন্য ঠিক আছে , যেহেতু আপনি যে পদ্ধতিগুলির বিষয়ে সত্যই যত্নবান হন কেবল সেই পদ্ধতিতে যাদুর পদ্ধতি রয়েছে যা উদাহরণটিকে উপেক্ষা করে তবে আরও জটিল উত্তরাধিকার কাঠামোর জন্য আপনি পিতামাতার কাছ থেকে কোনও কিছুর উত্তরাধিকারী হওয়ার ক্ষমতা সম্পূর্ণভাবে সরিয়ে ফেলেন। object
নতুন স্টাইলের ক্লাসগুলি উত্তরাধিকার সূত্রে objectবা অন্য নতুন শৈলীর শ্রেণীর কাছ থেকে:
class SomeObject(object):
pass
class SubObject(SomeObject):
pass
পুরানো স্টাইলের ক্লাসগুলি এটি করে না:
class SomeObject:
pass
এটি কেবল পাইথন 2 এ প্রযোজ্য - পাইথন 3 এ উপরের সমস্তগুলি নতুন-স্টাইলের ক্লাস তৈরি করবে।
দেখুন 9. ক্লাস (পাইথন টিউটোরিয়াল), NewClassVsClassicClass এবং পুরানো শৈলী এবং পাইথন নতুন শৈলী শ্রেণীর মধ্যে পার্থক্য কি? বিস্তারিত জানার জন্য.
নতুন স্টাইলের ক্লাসগুলি এমন হয় যা সাবক্লাসটি "অবজেক্ট" (প্রত্যক্ষ বা পরোক্ষভাবে) সাবক্লাস করে। এগুলির একটি __new__শ্রেণিক পদ্ধতি ছাড়াও __init__কিছুটা যুক্তিযুক্ত নিম্ন-স্তরের আচরণ রয়েছে।
সাধারণত, আপনি ওভাররাইড করতে চাইবেন __getattr__(যদি আপনিও ওভাররাইড করছেন) তবে অন্যথায় আপনার পদ্ধতিগুলির মধ্যে "সেলফুফু" সিনট্যাক্সকে সমর্থন করতে আপনার একটি কঠিন সময় কাটাতে হবে।
অতিরিক্ত তথ্য: http://www.devx.com/opensource/Article/31482/0/page/4
বেজলি এবং জোন্স পিসিবি পড়ার সময়, আমি একটি স্পষ্ট এবং ব্যবহারিক ব্যবহারের ক্ষেত্রে হোঁচট খেয়েছি __getattr__যে এর জন্য ওপি-র প্রশ্নের "যখন" অংশটির উত্তর দিতে সহায়তা করে। বইটি থেকে:
" __getattr__()বৈশিষ্ট্যটি অনুসন্ধানের জন্য পদ্ধতিটি এক ধরণের মত। এটি এমন একটি পদ্ধতি যা কোডটি উপস্থিত না হয়ে এমন একটি বৈশিষ্ট্য অ্যাক্সেস করার চেষ্টা করে যদি কল হয়" " আমরা উপরের উত্তরগুলি থেকে এটি জানি, কিন্তু পিসিবি রেসিপি 8.15 এ এই কার্যকারিতাটি প্রতিনিধিদলের নকশার প্যাটার্ন প্রয়োগ করতে ব্যবহৃত হয় । যদি অবজেক্ট এ এর একটি বৈশিষ্ট্যযুক্ত অবজেক্ট বি থাকে যা অবজেক্ট এ এর অবজেক্ট বি এর সমস্ত পদ্ধতি পুনরায় সংজ্ঞায়িত না করে কেবল অবজেক্ট বি এর পদ্ধতিগুলি কল করার জন্য অনেকগুলি পদ্ধতি প্রয়োগ করে যা অবিলম্বে এটিকে প্রতিনিধিত্ব করতে চায়, নীচে একটি __getattr__()পদ্ধতি নির্ধারণ করুন :
def __getattr__(self, name):
return getattr(self._b, name)
যেখানে _ বি হ'ল অবজেক্ট এ এর গুণাবলীর নাম যা একটি অবজেক্ট বি। যখন অবজেক্ট বিতে সংজ্ঞায়িত পদ্ধতিটি অবজেক্ট এতে ডাকা হয়, তখন __getattr__পদ্ধতিটি অনুসন্ধান শৃঙ্খলের শেষে ডাকা হবে। এটি কোড ক্লিনারটিকেও পরিষ্কার করে দেবে, যেহেতু আপনার কাছে কেবল অন্য কোনও বস্তুতে অর্পণ করার জন্য সংজ্ঞায়িত পদ্ধতির একটি তালিকা নেই।