2010-09-23 12 views
7

self._age चर का उपयोग करने का क्या कारण है? एक समान नाम जो पहले से इस्तेमाल किए गए self.age से लिंक नहीं है?पायथन में गुण

class newprops(object): 
    def getage(self): 
     return 40 
    def setage(self, value): 
     self._age = value 
    age = property(getage, setage, None, None) 
+7

'वापसी 40' - मुझे xkcd के यादृच्छिक संख्या जनरेटर की याद दिलाता है! – katrielalex

उत्तर

11

self.age पहले से ही संपत्ति द्वारा कब्जा कर लिया गया है, तो आपको वास्तविक चर पर एक और नाम देना होगा, जो _age है।

Btw, अजगर 2.6 के बाद से, आप सज्जाकार के साथ इस लिख सकते हैं: क्योंकि गेटर एक निरंतर रिटर्न

def newprops(object): 

    @property 
    def age(self): 
     return 40 

    @age.setter 
    def age(self, value): 
     self._age = value 
+3

अंडरस्कोर से शुरू होने वाले नाम का उपयोग करने का एक और फायदा है: यह "निजी" के लिए आमतौर पर मान्यता प्राप्त नामकरण सम्मेलन है (= "जब तक आपको जरूरी न हो तब तक स्पर्श न करें") चीजें। – delnan

+0

और डबल अंडरस्कोर से शुरू होने वाले नाम का उपयोग करना "वास्तव में निजी" के लिए आमतौर पर मान्यता प्राप्त सम्मेलन है। पाइथन के नास्टियर वारों में से एक में, डबल-अंडरस्कोर नाम उलझन में हैं ताकि आप उन्हें तब तक नहीं बुला सकें जब तक कि आप खुद को उलझाना नहीं चाहते! – katrielalex

+0

@ डेलनान: मैं कहूंगा कि यह "संरक्षित" के लिए सम्मेलन है, और अत्यधिक सावधानीपूर्वक प्रोग्रामर छद्म-निजी नाम मैंगलिंग सुविधा का उपयोग कुछ हद तक "निजी" चर के अनुकरण के लिए करते हैं। – AndiDog

0

जो आपने लिखा है वह कभी भी पायथन में नहीं लिखा जाएगा। अक्सर, हालांकि, ऐसी गतिविधियां होती हैं जिन्हें संपत्ति (जैसे क्रमबद्धता) सहेजते समय किया जाना चाहिए, और इसे किसी संपत्ति में पारदर्शी रूप से कैश किया जा सकता है।

चूंकि किसी संपत्ति को कॉल करने और किसी सदस्य तक पहुंचने के लिए प्रोटोकॉल समान है, इसलिए पाइथन शैली को सदस्य चर को गुणों में बदलने के लिए जितना संभव हो सके प्रतीक्षा करना है।

+0

"आपने जो लिखा वह कभी भी पायथन में नहीं लिखा जाएगा।" मार्क लुटज़ को बताओ। उन्होंने इसे अपनी पुस्तक में लिखा था! – MrMas

4

आपका उदाहरण वास्तव में बकवास है। आम तौर पर में एक अलग अंडरस्कोर नाम चर गुणों के साथ संयोजन के रूप में इस्तेमाल किया है, जो

1 हो सकता है) केवल पढ़ने के लिए

class C(object): 
    @property 
    def age(self): 
     return self._age 

इस मामले में, instance.age केवल पढ़ा जा सकता है, लेकिन करने के लिए आवंटित नहीं। सम्मेलन आंतरिक रूप से self._age पर लिखना है।

2) पढ़ने-लिखने की

class C(object): 
    @property 
    def age(self): 
     return self._age 

    @age.setter 
    def age(self, value): 
     assert value >= 0 
     self._age = value 

गेटर और सेटर केवल समझ में आता है कि आप जब मान निर्दिष्ट अतिरिक्त गणना या चेक करना है, तो होने। यदि नहीं, तो आप अंडरस्कोर के बिना चर को घोषित कर सकते हैं, क्योंकि गुण और आवृत्ति चर उसी तरह से पहुंचते हैं (कोड के संदर्भ में)। यही कारण है कि _age और संपत्ति age पाठ्यक्रम का अलग-अलग नाम दिया जाना चाहिए।

+0

सही! धन्यवाद। मैं इस पुस्तक के माध्यम से जा रहा हूं, और यह उदाहरण था ... मैं डब्ल्यूटीएफ की तरह था, यह कहां से आया? पहले उदाहरण में – shawn

+0

, 'instance.age' निश्चित रूप से असाइन किया जा सकता है। 'Instance.age = sqlite3.connect (': memory:') 'आज़माएं। क्योंकि यह '__set__' को परिभाषित नहीं करता है, कोई भी असाइनमेंट सीधे '__dict__' उदाहरणों में जाता है और वर्णनकर्ता तक पहुंचने के भविष्य के प्रयास सीधे' __dict__' पर जाते हैं। – aaronasterling

+0

यदि आप केवल पढ़ने योग्य संपत्ति चाहते हैं, तो '__set__' को 'एट्रिब्यूट एरर' बढ़ाने के लिए परिभाषित करें – aaronasterling

6

कुछ ऑब्जेक्ट उन्मुख भाषाओं को निजी विशेषताएँ कहा जाता है, जिन्हें क्लास विधियों के बाहर से एक्सेस नहीं किया जा सकता है। यह महत्वपूर्ण है क्योंकि कुछ विशेषताओं को सीधे बदलने के लिए नहीं हैं, इसके बजाय, उन्हें किसी अन्य चीज़ के कार्य के रूप में बदला जाना है, या वे बदलने से पहले मान्य हैं। पायथन में आपके पास निजी विशेषताएँ नहीं हैं, लेकिन आप गेटर्स और सेटर्स का उपयोग करके एक चर को लागू कर सकते हैं जो अंडरस्कोर से शुरू होता है - निजी तरीकों और विशेषताओं के लिए पायथन का सम्मेलन।

उदाहरण के लिए। आयताकार त्रिभुज का hypotenuse h=sqrt(a*a+b*b) द्वारा दिया जाता है, इसलिए आप सीधे h नहीं बदल सकते क्योंकि संबंध होना चाहिए। साथ ही, कहें कि मुझे नाम LASTNAME COMMA FIRSTNAME प्रारूप में होना चाहिए, तो आपको यह सत्यापित करना होगा कि self.lastname असाइन करने से पहले यह मामला है।

संपत्ति गेटर आपको hypotenuse प्राप्त करने की अनुमति देता है, लेकिन इसे स्थापित करने से आपको रोकता है। प्रॉपर्टी सेटर आपको एक संपत्ति सेट करने की इजाजत देता है लेकिन आप वास्तव में संपत्ति को सेट करने से पहले चेक कर सकते हैं।

तो:

class Person(object) 
def __init__(self): 
    # The actual attribute is _name 
    self._name = None 
@property 
def name(self): 
    # when I ask for the name, I mean to get _name 
    return self._name 
@name.setter 
def name(self, value): 
    # before setting name I can ensure that it has the right format 
    if regex_name.match(value): 
    # assume you have a regular expression to check for the name 
    self._name = value 
    else: 
    raise ValueError('invalid name') 

एक और उदाहरण:

class Triangle(object): 
def __init__(self, a, b): 
    # here a and b do not need to be private because 
    # we can change them at will. However, you could 
    # make them private and ensure that they are floats 
    # when they are changed 
    self.a = a 
    self.b = b 
@property 
def h(self): 
    return math.sqrt(a*a+b*b) 
# notice there is no h.setter - you cannot set h directly 
+2

महान उदाहरण, प्रभावी टिप्पणियां। – Air

संबंधित मुद्दे