जवाबों:
गुण एक विशेष प्रकार की विशेषता है। मूल रूप से, जब पायथन का सामना निम्नलिखित कोड से होता है:
spam = SomeObject()
print(spam.eggs)
यह लग रहा है eggsमें spam, और उसके बाद की जांच करता है eggsअगर यह एक को देखने के लिए __get__, __set__या __delete__विधि - अगर यह होता है, यह एक संपत्ति है। यदि यह है एक संपत्ति के बजाय सिर्फ लौटने की eggsवस्तु (के रूप में यह किसी भी अन्य विशेषता के लिए) यह फोन करेगा __get__विधि और बदले जो कुछ भी विधि रिटर्न (क्योंकि हम देखने कर रहे थे)।
पायथन के डेटा मॉडल और विवरणकर्ताओं के बारे में अधिक जानकारी ।
एक संपत्ति के साथ आपके पास इसके गेटटर, सेटर और डेलेटर विधियों पर पूरा नियंत्रण होता है, जो आपके पास एक विशेषता के साथ (यदि कैविट्स का उपयोग नहीं कर रहा है) नहीं है।
class A(object):
_x = 0
'''A._x is an attribute'''
@property
def x(self):
'''
A.x is a property
This is the getter method
'''
return self._x
@x.setter
def x(self, value):
"""
This is the setter method
where I can check it's not assigned a value < 0
"""
if value < 0:
raise ValueError("Must be >= 0")
self._x = value
>>> a = A()
>>> a._x = -1
>>> a.x = -1
Traceback (most recent call last):
File "ex.py", line 15, in <module>
a.x = -1
File "ex.py", line 9, in x
raise ValueError("Must be >= 0")
ValueError: Must be >= 0
x। एक रास्ता। यदि कक्षा के उपयोगकर्ता को _x के बारे में पता चलता है, तो वे इसका उपयोग अपने जोखिम पर करते हैं।
सामान्य शब्दों में एक संपत्ति और एक विशेषता एक ही बात है। हालांकि, पायथन में एक संपत्ति डेकोरेटर है जो एक विशेषता (या अन्य डेटा) को गेट्टर / सेटर एक्सेस प्रदान करता है।
class MyObject(object):
# This is a normal attribute
foo = 1
@property
def bar(self):
return self.foo
@bar.setter
def bar(self, value):
self.foo = value
obj = MyObject()
assert obj.foo == 1
assert obj.bar == obj.foo
obj.bar = 2
assert obj.foo == 2
assert obj.bar == obj.foo
संपत्ति आपको सामान्य विशेषताओं की तरह मान प्राप्त करने और सेट करने की अनुमति देती है, लेकिन इसके नीचे एक विधि है जिसे आप के लिए एक गेट्टर और सेटर में अनुवाद करना कहा जा रहा है। यह वास्तव में सिर्फ कॉलिंग गेटर्स और बसने वालों के बॉयलरप्लेट पर कटौती करने की सुविधा है।
उदाहरण के लिए कहते हैं, आपके पास एक ऐसा वर्ग था जो आपकी आवश्यकता के लिए कुछ x और y निर्देशांक रखता था। उन्हें सेट करने के लिए आप कुछ ऐसा करना चाहते हैं:
myObj.x = 5
myObj.y = 10
यह देखने और लिखने की तुलना में सोचने में बहुत आसान है:
myObj.setX(5)
myObj.setY(10)
समस्या यह है कि क्या होगा अगर एक दिन आपकी कक्षा ऐसी बदल जाए कि आपको अपने x और y को किसी मूल्य से ऑफसेट करने की आवश्यकता हो? अब आपको अपनी कक्षा की परिभाषा को बदलने और इसे कॉल करने वाले सभी कोड को बदलने की आवश्यकता होगी, जो वास्तव में समय लेने वाली और त्रुटि प्रवण हो सकती है। संपत्ति आपको बाद के परिवर्तन के लचीलेपन को देते हुए पूर्व वाक्यविन्यास का उपयोग करने की अनुमति देती है।
पायथन में, आप संपत्ति फ़ंक्शन के साथ गेटर्स, सेटर्स और डिलीट तरीकों को परिभाषित कर सकते हैं। यदि आप सिर्फ पढ़ी गई संपत्ति चाहते हैं, तो एक @property डेकोरेटर भी है जिसे आप अपने तरीके से जोड़ सकते हैं।
मैंने सारांश में बेरंड क्लेन की साइट से 2 अंतर सीखे :
1. संपत्ति डेटा एनकैप्सुलेशन करने का एक अधिक सुविधाजनक तरीका है।
पूर्व: यदि आपकी कोई सार्वजनिक विशेषता ऑब्जेक्ट के बाद में है, तो बाद में, आपकी परियोजना को आपको इसे एनकैप्सुलेट करना होगा, अर्थात: इसे निजी में बदलें और गेट्टर और सेटर प्रदान करें => आपको पहले लिखे गए कई कोड बदलने होंगे:
#Old codes
obj1.length=obj1.length+obj2.length
#New codes(Using private attibutes and getter and setter)
obj1.set_lenght(obj1.get_length()+obj2.get_length()) #=> this is ugly
यदि आप @property और @ lenght.setter => का उपयोग करते हैं, तो आपको उन पुराने कोड को बदलने की आवश्यकता नहीं है
2. एक संपत्ति कई विशेषताओं को अतिक्रमण कर सकती है
class Person:
def __init__(self, name, physic_health, mental_health):
self.name=name
self.__physic_health=physic_health #physic_health is real value in range [0, 5.0]
self.__mental_health=mental_health #mental_health is real value in range [0, 5.0]
@property
def condition(self):
health=self.__physic_health+self.__mental_health
if(health<5.0):
return "I feel bad!"
elif health<8.0:
return "I am ok!"
else:
return "Great!"
इस उदाहरण में, __physic_healthऔर __mental_healthनिजी हैं और उन्हें सीधे बाहर से एक्सेस नहीं किया जा सकता है, उनके साथ कक्षा के बाहर बातचीत का एकमात्र तरीका संपत्ति हैcondition
वहाँ भी एक स्पष्ट अंतर नहीं है कि मैं कैश या रिफ्रेश डेटा का उपयोग करता हूं, अक्सर हमारे पास क्लास विशेषता से जुड़ा एक फ़ंक्शन होता है। उदाहरण के लिए, मुझे एक बार फाइल पढ़ने की जरूरत है और सामग्री को विशेषता के लिए सौंपा जाना चाहिए ताकि मूल्य कैश हो जाए:
class Misc():
def __init__(self):
self.test = self.test_func()
def test_func(self):
print 'func running'
return 'func value'
cl = Misc()
print cl.test
print cl.test
आउटपुट:
func running
func value
func value
हमने विशेषता को दो बार एक्सेस किया लेकिन हमारा फ़ंक्शन केवल एक बार निकाल दिया गया था। संपत्ति का उपयोग करने के लिए उपरोक्त उदाहरण को बदलने से आपके द्वारा उपयोग किए जाने पर प्रत्येक बार विशेषता का मूल्य ताज़ा हो जाएगा:
class Misc():
@property
def test(self):
print 'func running'
return 'func value'
cl = Misc()
print cl.test
print cl.test
आउटपुट:
func running
func value
func running
func value