पायथन में एक वर्ग 'सदस्य चर तक पहुँच?


85
class Example(object):
    def the_example(self):
        itsProblem = "problem"

theExample = Example()
print(theExample.itsProblem)

मैं एक वर्ग के चर का उपयोग कैसे करूं? मैंने इस परिभाषा को जोड़ने की कोशिश की है:

def return_itsProblem(self):
    return itsProblem

फिर भी, यह भी विफल रहता है।


1
शीर्षक संपादित, वास्तव में वर्ग "स्थिर" चर के बारे में सवाल: stackoverflow.com/questions/707380/…
Ciro Santilli Sant about about about 法轮功 '

जवाबों:


144

जवाब, कुछ शब्दों में

आपके उदाहरण में, itsProblemएक स्थानीय चर है।

selfउदाहरण चर सेट करने और प्राप्त करने के लिए आपका उपयोग करना चाहिए । आप इसे __init__विधि में सेट कर सकते हैं । फिर आपका कोड होगा:

class Example(object):
    def __init__(self):
        self.itsProblem = "problem"


theExample = Example()
print(theExample.itsProblem)

लेकिन अगर आप एक सच्चे वर्ग चर चाहते हैं, तो सीधे वर्ग नाम का उपयोग करें:

class Example(object):
    itsProblem = "problem"


theExample = Example()
print(theExample.itsProblem)
print (Example.itsProblem)

लेकिन इस एक के साथ सावधान रहें, जैसा theExample.itsProblemकि स्वचालित रूप से इसके बराबर होना तय हैExample.itsProblem , लेकिन बिल्कुल समान चर नहीं है और इसे स्वतंत्र रूप से बदला जा सकता है।

कुछ स्पष्टीकरण

पायथन में, चर गतिशील रूप से बनाए जा सकते हैं। इसलिए, आप निम्न कार्य कर सकते हैं:

class Example(object):
    pass

Example.itsProblem = "problem"

e = Example()
e.itsSecondProblem = "problem"

print Example.itsProblem == e.itsSecondProblem 

प्रिंट

सच

इसलिए, यह वही है जो आप पिछले उदाहरणों के साथ करते हैं।

वास्तव में, पायथन में हम इसका उपयोग selfकरते हैं this, लेकिन यह उससे थोड़ा अधिक है। selfकिसी भी वस्तु पद्धति का पहला तर्क है क्योंकि पहला तर्क हमेशा वस्तु संदर्भ होता है। यह स्वचालित है, चाहे आप इसे कॉल करें selfया नहीं।

जिसका अर्थ है आप कर सकते हैं:

class Example(object):
    def __init__(self):
        self.itsProblem = "problem"


theExample = Example()
print(theExample.itsProblem)

या:

class Example(object):
    def __init__(my_super_self):
        my_super_self.itsProblem = "problem"


theExample = Example()
print(theExample.itsProblem)

बिलकुल ऐसा ही है। किसी भी ऑब्जेक्ट विधि का पहला तर्क वर्तमान ऑब्जेक्ट है, हम केवल इसे selfएक सम्मेलन के रूप में कहते हैं । और आप इस ऑब्जेक्ट में सिर्फ एक चर जोड़ते हैं, उसी तरह आप इसे बाहर से करते हैं।

अब, वर्ग चर के बारे में।

जब तुम करोगे:

class Example(object):
    itsProblem = "problem"


theExample = Example()
print(theExample.itsProblem)

आप देखेंगे कि हम पहले एक वर्ग चर सेट करते हैं , फिर हम एक वस्तु (उदाहरण) चर का उपयोग करते हैं । हम इस ऑब्जेक्ट चर को कभी सेट नहीं करते हैं लेकिन यह काम करता है, यह कैसे संभव है?

ठीक है, पायथन पहले ऑब्जेक्ट चर प्राप्त करने की कोशिश करता है, लेकिन अगर यह नहीं मिल सकता है, तो आपको कक्षा चर देगा। चेतावनी: वर्ग चर को उदाहरणों के बीच साझा किया जाता है, और ऑब्जेक्ट चर नहीं है।

निष्कर्ष के रूप में, ऑब्जेक्ट चर के लिए डिफ़ॉल्ट मान सेट करने के लिए कभी भी वर्ग चर का उपयोग न करें। उपयोग__init__

आखिरकार, आप सीखेंगे कि पायथन कक्षाएं उदाहरण हैं और इसलिए खुद को ऑब्जेक्ट करता है, जो उपरोक्त समझने के लिए नई अंतर्दृष्टि देता है। वापस आओ और इसे बाद में फिर से पढ़ें, एक बार जब आप महसूस करते हैं।


आप कहते हैं: "theExample.itsProblem स्वचालित रूप से example.itsProblem के बराबर होने के लिए सेट है, लेकिन सभी समान वेरिएबल नहीं है और इसे स्वतंत्र रूप से बदला जा सकता है" - लेकिन यह काफी सही नहीं है, और आपका वाक्यांश भ्रामक है। मुझे विश्वास है कि आप जानते हैं कि वहां क्या चल रहा है, इसलिए मैं सुझाव देता हूं कि: "यह एक ही चर है, लेकिन इसे प्रत्येक वस्तु के लिए स्वतंत्र रूप से रिबंड किया जा सकता है"।
jsbueno

हां, लेकिन बाध्यकारी एक अवधारणा है जो किसी अन्य प्रोग्रामिंग भाषा जैसे कि जावा या सी (जैसा कि मुझे संदेह है कि ओपी है) के लिए पूर्ण रूप से अज्ञात है। फिर मैं यह बताना चाहूंगा कि बाध्यकारी क्या है, फिर देर से बाध्यकारी, फिर उत्परिवर्तित वस्तुओं के संदर्भ में समस्या। यह बहुत लंबा होगा। मुझे लगता है कि किसी समय आपको समझ की वेदी पर सटीक बलिदान करना होगा।
ई-सटिस

वहाँ भी है (मुझे लगता है कि यह 2.7+ हो सकता है) @क्लासमेथोड डेकोरेटर, देखने लायक है। यहाँ दिलचस्प चर्चा - stackoverflow.com/questions/12179271/…
jsh

1
name-बाध्यकारी: मुझे लगता है कि गलत बयान देना एक बुरा विचार है, चाहे कोई भी स्तर हो। मैं इसे थोड़ा संपादित करने का सुझाव देता हूं: लेकिन इस एक के साथ सावधान रहें, जैसा theExample.itsProblemकि स्वचालित रूप से इसके बराबर होने के लिए सेट है Example.itsProblem, लेकिन, व्यावहारिक दृष्टिकोण से *, एक ही चर बिल्कुल नहीं है और इसे स्वतंत्र रूप से बदला जा सकता है। *: वास्तव में यह एक ही वस्तु के रूप में शुरू होता है, लेकिन गलती से बदलना बहुत आसान है कि अगर आप पायथन के नाम-बंधन को
n611x007

11

आप स्थानीय चर घोषित कर रहे हैं, वर्ग चर नहीं। एक उदाहरण चर (विशेषता) सेट करने के लिए, का उपयोग करें

class Example(object):
    def the_example(self):
        self.itsProblem = "problem"  # <-- remember the 'self.'

theExample = Example()
theExample.the_example()
print(theExample.itsProblem)

एक वर्ग चर (उर्फ स्थिर सदस्य) सेट करने के लिए , का उपयोग करें

class Example(object):
    def the_example(self):
        Example.itsProblem = "problem"
        # or, type(self).itsProblem = "problem"
        # depending what you want to do when the class is derived.

1
सिवाय इसके कि कक्षा-चर एक बार कक्षा-स्तर पर घोषित किए जाते हैं । आपका रास्ता इसे हर संस्थान पर रीसेट कर देगा, यह वास्तव में वह नहीं है जो आप चाहते हैं। स्पष्ट स्व के पीछे तर्क के लिए stackoverflow.com/questions/2709821/python-self-explained भी देखें ।

2

यदि आपके पास एक उदाहरण समारोह है (अर्थात जो स्वयं पास हो जाता है) तो आप स्वयं का उपयोग करके कक्षा का संदर्भ प्राप्त कर सकते हैं self.__class__

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

import tornado.web
import riak

class get_handler(tornado.web.requestHandler):
    riak_client = None

    def post(self):
        cls = self.__class__
        if cls.riak_client is None:
            cls.riak_client = riak.RiakClient(pb_port=8087, protocol='pbc')
        # Additional code to send response to the request ...
    

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

पाठकों को चेतावनी दी जानी चाहिए कि ऊपर की तरह एक हैंडलर का उपयोग न केवल सिंगलथ्रेडेड अनुप्रयोगों में समस्याएं पैदा कर सकता है। वर्ग के उत्परिवर्ती उदाहरण सिद्धांत में समान हैंडलर iin समानांतर का उपयोग कर सकते हैं, और यदि हैंडलर को ऐसा करने के लिए डिज़ाइन नहीं किया गया है, जो इसकी आंतरिक संरचना पर निर्भर करता है, तो यह काम नहीं कर सकता है। एकल थ्रेडेड एप्लिकेशन में 'समानांतर में' का अर्थ है, हैंडलर का उपयोग करके प्रथम श्रेणी का उदाहरण समाप्त नहीं हुआ है और फिर दूसरा उदाहरण हैंडलर का उपयोग करना शुरू करता है। इस तरह के मामलों में इसके बजाय एक उदाहरण चर का उपयोग करने की सलाह दी जा सकती है।
मीत

0

नीचे दिए गए उदाहरण की तरह रिटर्न स्टेटमेंट को लागू करें! आपको अच्छा होना चाहिए। मुझे आशा है कि यह किसी की मदद करता है ..

class Example(object):
    def the_example(self):
        itsProblem = "problem"
        return itsProblem 


theExample = Example()
print theExample.the_example()

1
आपको अपना कोड इंडेंटेशन ठीक करना चाहिए। इस सवाल के बेहतर उत्तर भी हैं और आपका उत्तर उन उत्तरों पर एक बुनियादी बदलाव है, वैकल्पिक समाधान नहीं ...
HEADLESS_0NE
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.