Python Language
डिस्क्रिप्टर
खोज…
सरल वर्णन करनेवाला
दो अलग-अलग प्रकार के वर्णनकर्ता हैं। डेटा डिस्क्रिप्टर को ऑब्जेक्ट के रूप में परिभाषित किया जाता है जो __get__()
और __set__()
विधि दोनों को परिभाषित करते हैं, जबकि गैर-डेटा डिस्क्रिप्टर केवल __get__()
विधि को परिभाषित करते हैं। ओवरराइड्स और एक उदाहरण के शब्दकोश के नामस्थान पर विचार करते समय यह अंतर महत्वपूर्ण है। यदि एक डेटा डिस्क्रिप्टर और एक इंस्टेंस के शब्दकोश में एक ही नाम साझा करते हैं, तो डेटा डिस्क्रिप्टर पूर्वता लेगा। हालाँकि, अगर इसके बजाय एक गैर-डेटा डिस्क्रिप्टर और एक इंस्टेंस के शब्दकोश में एक ही नाम साझा करते हैं, तो उदाहरण डिक्शनरी की प्रविष्टि पूर्वता लेगी।
केवल पढ़ने के लिए डेटा वर्णनकर्ता बनाने के लिए, सेट () जब नामक एक AttributeError को ऊपर उठाने के साथ दोनों get () और सेट () निर्धारित करते हैं। सेट () विधि को एक अपवाद बढ़ाने वाले प्लेसहोल्डर के साथ परिभाषित करना इसे डेटा विवरणक बनाने के लिए पर्याप्त है।
descr.__get__(self, obj, type=None) --> value
descr.__set__(self, obj, value) --> None
descr.__delete__(self, obj) --> None
एक कार्यान्वित उदाहरण:
class DescPrinter(object):
"""A data descriptor that logs activity."""
_val = 7
def __get__(self, obj, objtype=None):
print('Getting ...')
return self._val
def __set__(self, obj, val):
print('Setting', val)
self._val = val
def __delete__(self, obj):
print('Deleting ...')
del self._val
class Foo():
x = DescPrinter()
i = Foo()
i.x
# Getting ...
# 7
i.x = 100
# Setting 100
i.x
# Getting ...
# 100
del i.x
# Deleting ...
i.x
# Getting ...
# 7
दो तरफा रूपांतरण
वर्णनात्मक ऑब्जेक्ट संबंधित ऑब्जेक्ट विशेषताओं को स्वचालित रूप से परिवर्तनों पर प्रतिक्रिया करने की अनुमति दे सकते हैं।
मान लें कि हम एक दिए गए आवृत्ति (हर्ट्ज में) और अवधि (सेकंड में) के साथ एक थरथरानवाला मॉडल करना चाहते हैं। जब हम आवृत्ति को अपडेट करना चाहते हैं, तो हम अपडेट करने की अवधि चाहते हैं, और जब हम उस अवधि को अपडेट करते हैं, तो हम अपडेट करने की आवृत्ति चाहते हैं:
>>> oscillator = Oscillator(freq=100.0) # Set frequency to 100.0 Hz
>>> oscillator.period # Period is 1 / frequency, i.e. 0.01 seconds
0.01
>>> oscillator.period = 0.02 # Set period to 0.02 seconds
>>> oscillator.freq # The frequency is automatically adjusted
50.0
>>> oscillator.freq = 200.0 # Set the frequency to 200.0 Hz
>>> oscillator.period # The period is automatically adjusted
0.005
हम मूल्यों में से एक (आवृत्ति, हर्ट्ज में) को "लंगर" के रूप में चुनते हैं, अर्थात वह जो बिना रूपांतरण के साथ सेट किया जा सकता है, और इसके लिए एक डिस्क्रिप्टर क्लास लिखें:
class Hertz(object):
def __get__(self, instance, owner):
return self.value
def __set__(self, instance, value):
self.value = float(value)
लंगर के संदर्भ में "अन्य" मान (अवधि, सेकंड में) परिभाषित किया गया है। हम एक डिस्क्रिप्टर क्लास लिखते हैं जो हमारा रूपांतरण करता है:
class Second(object):
def __get__(self, instance, owner):
# When reading period, convert from frequency
return 1 / instance.freq
def __set__(self, instance, value):
# When setting period, update the frequency
instance.freq = 1 / float(value)
अब हम ऑसिलेटर श्रेणी लिख सकते हैं:
class Oscillator(object):
period = Second() # Set the other value as a class attribute
def __init__(self, freq):
self.freq = Hertz() # Set the anchor value as an instance attribute
self.freq = freq # Assign the passed value - self.period will be adjusted