शुरुआत करते हैं पायथन डेकोरेटर्स से।
पायथन डेकोरेटर एक फ़ंक्शन है जो पहले से परिभाषित फ़ंक्शन में कुछ अतिरिक्त फ़ंक्शंस जोड़ने में मदद करता है।
अजगर में, सब कुछ एक वस्तु है। पायथन में फ़ंक्शंस प्रथम श्रेणी की वस्तुएं हैं, जिसका अर्थ है कि उन्हें एक चर द्वारा संदर्भित किया जा सकता है, सूचियों में जोड़ा गया, किसी अन्य फ़ंक्शन के तर्क के रूप में पारित किया गया आदि।
निम्नलिखित कोड स्निपेट पर विचार करें।
def decorator_func(fun):
def wrapper_func():
print("Wrapper function started")
fun()
print("Given function decorated")
# Wrapper function add something to the passed function and decorator
# returns the wrapper function
return wrapper_func
def say_bye():
print("bye!!")
say_bye = decorator_func(say_bye)
say_bye()
# Output:
# Wrapper function started
# bye
# Given function decorated
यहाँ, हम कह सकते हैं कि डेकोरेटर फ़ंक्शन ने हमारे say_hello फ़ंक्शन को संशोधित किया और इसमें कोड की कुछ अतिरिक्त लाइनें जोड़ीं।
डेकोरेटर के लिए पायथन सिंटैक्स
def decorator_func(fun):
def wrapper_func():
print("Wrapper function started")
fun()
print("Given function decorated")
# Wrapper function add something to the passed function and decorator
# returns the wrapper function
return wrapper_func
@decorator_func
def say_bye():
print("bye!!")
say_bye()
चलो एक मामले के परिदृश्य की तुलना में सब कुछ समाप्त कर देते हैं, लेकिन इससे पहले आइए कुछ ऊप्स प्रिंसीपल के बारे में बात करते हैं।
डेटा इनकैप्सुलेशन के सिद्धांत को सुनिश्चित करने के लिए कई ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग लैंग्वेज में गेटर्स और सेटर का उपयोग किया जाता है (इसे इन डेटा पर काम करने वाले तरीकों के साथ डेटा के बंडल के रूप में देखा जाता है।)
ये तरीके निश्चित रूप से डेटा को पुनः प्राप्त करने के लिए और डेटा को बदलने के लिए सेटर हैं।
इस सिद्धांत के अनुसार, एक वर्ग की विशेषताओं को अन्य कोड से छिपाने और उनकी रक्षा करने के लिए निजी बनाया जाता है।
हाँ, @property मूल रूप से एक है से गेटर्स और सेटर का उपयोग करने के लिए पायथोनिक तरीका है।
पायथन में एक महान अवधारणा है जिसे संपत्ति कहा जाता है जो ऑब्जेक्ट-ओरिएंटेड प्रोग्रामर के जीवन को बहुत सरल बनाता है।
चलिए हम मान लेते हैं कि आप एक ऐसा वर्ग बनाने का निर्णय लेते हैं जो तापमान को डिग्री सेल्सियस में संग्रहित कर सके।
class Celsius:
def __init__(self, temperature = 0):
self.set_temperature(temperature)
def to_fahrenheit(self):
return (self.get_temperature() * 1.8) + 32
def get_temperature(self):
return self._temperature
def set_temperature(self, value):
if value < -273:
raise ValueError("Temperature below -273 is not possible")
self._temperature = value
Refactored Code, Here यह है कि हम इसे संपत्ति के साथ कैसे प्राप्त कर सकते हैं।
पायथन में, संपत्ति () एक अंतर्निहित फ़ंक्शन है जो एक संपत्ति ऑब्जेक्ट बनाता है और वापस करता है।
एक प्रॉपर्टी ऑब्जेक्ट में तीन तरीके होते हैं, गेट्टर (), सेटर (), और डिलीट ()।
class Celsius:
def __init__(self, temperature = 0):
self.temperature = temperature
def to_fahrenheit(self):
return (self.temperature * 1.8) + 32
def get_temperature(self):
print("Getting value")
return self.temperature
def set_temperature(self, value):
if value < -273:
raise ValueError("Temperature below -273 is not possible")
print("Setting value")
self.temperature = value
temperature = property(get_temperature,set_temperature)
यहाँ,
temperature = property(get_temperature,set_temperature)
के रूप में तोड़ा जा सकता था,
# make empty property
temperature = property()
# assign fget
temperature = temperature.getter(get_temperature)
# assign fset
temperature = temperature.setter(set_temperature)
नोट करने के लिए बिंदु:
- get_taper एक विधि के बजाय एक संपत्ति बना हुआ है।
अब आप लिखकर तापमान के मान को प्राप्त कर सकते हैं।
C = Celsius()
C.temperature
# instead of writing C.get_temperature()
हम आगे पर जा सकते हैं और नाम नहीं परिभाषित get_temperature और set_temperature के रूप में वे अनावश्यक हैं और वर्ग नामस्थान को दूषित।
Pythonic तरीका ऊपर समस्या से निपटने के उपयोग करने के लिए है @property ।
class Celsius:
def __init__(self, temperature = 0):
self.temperature = temperature
def to_fahrenheit(self):
return (self.temperature * 1.8) + 32
@property
def temperature(self):
print("Getting value")
return self.temperature
@temperature.setter
def temperature(self, value):
if value < -273:
raise ValueError("Temperature below -273 is not possible")
print("Setting value")
self.temperature = value
नोट करने के लिए अंक -
- एक विधि जिसका उपयोग मूल्य प्राप्त करने के लिए किया जाता है उसे "@property" से सजाया जाता है।
- जिस विधि को सेटर के रूप में कार्य करना होता है उसे "@ temperature.setter" से सजाया जाता है, यदि फ़ंक्शन को "x" कहा जाता था, तो हमें इसे "@ x.setter" से सजाना होगा।
- हमने एक ही नाम के साथ "दो" विधियां लिखीं और "डिफ तापमान (स्व)" और "डिफ टेम्परेचर (सेल्फ, एक्स)" के मापदंडों की एक अलग संख्या।
जैसा कि आप देख सकते हैं, कोड निश्चित रूप से कम सुरुचिपूर्ण है।
अब, एक वास्तविक जीवन के व्यावहारिक वैज्ञानिक के बारे में बात करते हैं।
मान लीजिए कि आपने निम्नानुसार एक वर्ग तैयार किया है:
class OurClass:
def __init__(self, a):
self.x = a
y = OurClass(10)
print(y.x)
अब, आगे मान लेते हैं कि हमारी कक्षा ग्राहकों के बीच लोकप्रिय हो गई और उन्होंने अपने कार्यक्रमों में इसका उपयोग करना शुरू कर दिया, उन्होंने ऑब्जेक्ट को सभी प्रकार के असाइनमेंट किए।
और एक भाग्यशाली दिन, एक विश्वसनीय ग्राहक हमारे पास आया और सुझाव दिया कि "x" को 0 और 1000 के बीच का मान होना चाहिए, यह वास्तव में एक भयानक परिदृश्य है!
गुणों के कारण यह आसान है: हम "x" का एक संपत्ति संस्करण बनाते हैं।
class OurClass:
def __init__(self,x):
self.x = x
@property
def x(self):
return self.__x
@x.setter
def x(self, x):
if x < 0:
self.__x = 0
elif x > 1000:
self.__x = 1000
else:
self.__x = x
यह बहुत अच्छा है, यह नहीं है: आप सबसे सरल कार्यान्वयन कल्पना के साथ शुरू कर सकते हैं, और आप इंटरफ़ेस बदलने के लिए बिना बाद में एक संपत्ति संस्करण में स्थानांतरित करने के लिए स्वतंत्र हैं! तो गुण सिर्फ गेटर्स और सेटर के लिए एक प्रतिस्थापन नहीं हैं!
आप इस कार्यान्वयन को यहां देख सकते हैं