पायथन में उदाहरण चर कैसे प्राप्त करें?


120

क्या सभी श्रेणी के उदाहरण चर की एक सरणी प्राप्त करने के लिए पायथन में एक अंतर्निहित पद्धति है? उदाहरण के लिए, यदि मेरे पास यह कोड है:

class hi:
  def __init__(self):
    self.ii = "foo"
    self.kk = "bar"

क्या मेरे लिए ऐसा करने का कोई तरीका है:

>>> mystery_method(hi)
["ii", "kk"]

संपादित करें: मैंने मूल रूप से कक्षा चर के लिए गलती से पूछा था।


आपका उदाहरण "उदाहरण चर" दिखाता है। वर्ग चर एक और चीज है।
:

जवाबों:


143

प्रत्येक ऑब्जेक्ट में एक __dict__चर होता है जिसमें सभी चर और इसके मूल्य होते हैं।

इसे इस्तेमाल करे

>>> hi_obj = hi()
>>> hi_obj.__dict__.keys()

7
एफडब्ल्यूआईडब्ल्यू, निरीक्षण मॉड्यूल आपको तानाशाही पर भरोसा करने की तुलना में अधिक विश्वसनीय तरीका देता है , जिसमें सभी उदाहरण नहीं हैं।
थॉमस वाउटर्स सिप

1
किस तरह का उदाहरण तानाशाही नहीं है ? मैंने कभी सामना नहीं किया।
कार्ल मेयर

3
कुछ अंतर्निहित प्रकार, जैसे कि इंट। "X = 5" कहने की कोशिश करें और फिर "x। _ Dict__" और आपको एक एट्रीब्यूट मिलेगा
एली कोर्टराइट

6
इसके अलावा, स्लॉट्स का उपयोग करने वाली कोई भी चीज़ ।
थॉमस वाउटर्स

2
क्यों आप एक उदाहरण के वर्ग उदाहरण चर कोशिश करना चाहते हैं? यह भी एक वर्ग नहीं है (हालांकि मैं उस पर गलत हो सकता है)।
मार्टिन शेरबर्न

103

Var () का उपयोग करें

class Foo(object):
    def __init__(self):
        self.a = 1
        self.b = 2

vars(Foo()) #==> {'a': 1, 'b': 2}
vars(Foo()).keys() #==> ['a', 'b']

6
+1 मुझे व्यक्तिगत रूप से लगता है कि यह वाक्यविन्यास तानाशाही का उपयोग करने की तुलना में क्लीनर है , क्योंकि डबल अंडरस्कोर के साथ विशेषताओं को पायथन सिंटैक्स में "निजी" माना जाता है।
मार्टिन डब्ल्यू

3
@ मॉर्टिन: __methodनिजी है, __method__एक विशेष विधि है, जरूरी नहीं कि निजी हो; मैं यह कहना चाहूंगा कि विशेष विधियाँ किसी वस्तु की क्षमताओं को परिभाषित करने के बजाय तरीकों को परिभाषित करती हैं।
u0b34a0f6ae

2
__method__काफी बदसूरत है, और मुझे लगता है कि उन्हें इस तरह नामित करने की कोशिश की गई है और लोगों को उनका उपयोग करने से दूर रखा जाए जब तक कि बिल्कुल आवश्यक न हो। इस मामले में हमारे पास वैकल्पिक संस्करण () हैं।
मार्टिन शेरबर्न

मेरे मामले में मैंने कॉलिंग वर्जन (ओबजनामे) की कोशिश की और यह एक डिक्शनरी के साथ एक डिक्ट्री_प्रोक्स लौटाता है जिसकी चाबियां दिए गए वर्ग / ऑब्जेक्ट के तरीके हैं, लेकिन इनट एलिमेंट्स का कोई संकेत नहीं है । कोई भी अनुमान क्यों?
user228137

डबल अंडरस्कोर चर __str__, __method__सामान्य रूप से भाषा के लिए ही हैं। क्या होता है जब आप str(something)?
Zizouz212

15

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

एक अपवाद यह है कि यदि आपकी कक्षा स्लॉट्स का उपयोग करती है, जो उन विशेषताओं की एक निश्चित सूची है, जो कक्षा में इंस्टेंस को रखने की अनुमति देती है। स्लॉट्स को http://www.python.org/2.2.3/descrintro.html में समझाया गया है , लेकिन स्लॉट्स के साथ विभिन्न नुकसान हैं; वे मेमोरी लेआउट को प्रभावित करते हैं, इसलिए एकाधिक वंशानुक्रम समस्याग्रस्त हो सकते हैं, और सामान्य रूप से विरासत में स्लॉट्स को भी ध्यान में रखना पड़ता है।


डाउनवोटिंग क्योंकि "आप इंस्टेंस विशेषताओं की सूची प्राप्त नहीं कर सकते हैं" बस गलत है: दोनों vars () और तानाशाह आपको बिल्कुल वही देते हैं।
कार्ल मेयर

2
मुझे लगता है कि उनका मतलब था "आप सभी संभावित उदाहरण विशेषताओं की सूची प्राप्त नहीं कर सकते हैं"। उदाहरण के लिए, मैं अक्सर आलसी पीढ़ी और @property डेकोरेटर का उपयोग करता हूं, उदाहरण के लिए पहली बार चर का अनुरोध करने के लिए। तानाशाह का उपयोग करने से आपको इस चर के बारे में पता चल जाएगा, लेकिन यह पहले से ही मौजूद था।
एली कोर्टराइट

5
मैंने इसे अस्वीकार नहीं किया, और कृपया ध्यान दें कि मैंने वास्तव में क्या कहा था: आपको सिर्फ एक वर्ग द्वारा दी गई उदाहरण विशेषताओं की सूची नहीं मिल सकती है , जो कि प्रश्न के साथ कोड क्या करने की कोशिश करता है।
थॉमस वाउचर

2
@ कार्ल: कृपया झूठी टिप्पणी लिखने से पहले खुद को शिक्षित करें और अपने ज्ञान की कमी को कम करें।
निको

14

Vars () और तानाशाही दोनों तरीके, उदाहरण के लिए ओपी द्वारा पोस्ट किए गए काम करेंगे, लेकिन वे "शिथिल" परिभाषित वस्तुओं के लिए काम नहीं करेंगे:

class foo:
  a = 'foo'
  b = 'bar'

सभी गैर-कॉल करने योग्य विशेषताओं को मुद्रित करने के लिए, आप निम्न फ़ंक्शन का उपयोग कर सकते हैं:

def printVars(object):
    for i in [v for v in dir(object) if not callable(getattr(object,v))]:
        print '\n%s:' % i
        exec('print object.%s\n\n') % i

5
exec('print object.%s\n\n') % iके रूप में लिखा जाना चाहिएprint getattr(object, i)
user102008

11

आप यह भी परख सकते हैं कि किसी वस्तु के साथ विशिष्ट चर है:

>>> hi_obj = hi()
>>> hasattr(hi_obj, "some attribute")

6

आपका उदाहरण "उदाहरण चर" दिखाता है, न कि वास्तव में वर्ग चर।

एक नज़र डालें जो hi_obj.__class__.__dict__.items()वर्ग चर के लिए, सदस्य कार्यों जैसे अन्य अन्य वर्ग के सदस्यों और युक्त मॉड्यूल के साथ।

class Hi( object ):
    class_var = ( 23, 'skidoo' ) # class variable
    def __init__( self ):
        self.ii = "foo" # instance variable
        self.jj = "bar"

वर्ग चर को कक्षा के सभी उदाहरणों द्वारा साझा किया जाता है।


6

सुझाना

>>> print vars.__doc__
vars([object]) -> dictionary

Without arguments, equivalent to locals().
With an argument, equivalent to object.__dict__.

दूसरे पासवर्डों में, यह अनिवार्य रूप से केवल __dict__ को लपेटता है


5

हालांकि सीधे ओपी सवाल का जवाब नहीं है, लेकिन यह पता लगाने का एक बहुत ही प्यारा तरीका है कि एक फ़ंक्शन में चर क्या गुंजाइश हैं। इस कोड पर एक नज़र डालें:

>>> def f(x, y):
    z = x**2 + y**2
    sqrt_z = z**.5
    return sqrt_z

>>> f.func_code.co_varnames
('x', 'y', 'z', 'sqrt_z')
>>> 

Func_code विशेषता में सभी प्रकार की दिलचस्प चीजें हैं। यह आपको कुछ शांत सामानों से बाहर निकलने की अनुमति देता है। यहाँ एक उदाहरण है कि मैंने इसका उपयोग कैसे किया है:

def exec_command(self, cmd, msg, sig):

    def message(msg):
        a = self.link.process(self.link.recieved_message(msg))
        self.exec_command(*a)

    def error(msg):
        self.printer.printInfo(msg)

    def set_usrlist(msg):
        self.client.connected_users = msg

    def chatmessage(msg):
        self.printer.printInfo(msg)

    if not locals().has_key(cmd): return
    cmd = locals()[cmd]

    try:
        if 'sig' in cmd.func_code.co_varnames and \
                       'msg' in cmd.func_code.co_varnames: 
            cmd(msg, sig)
        elif 'msg' in cmd.func_code.co_varnames: 
            cmd(msg)
        else:
            cmd()
    except Exception, e:
        print '\n-----------ERROR-----------'
        print 'error: ', e
        print 'Error proccessing: ', cmd.__name__
        print 'Message: ', msg
        print 'Sig: ', sig
        print '-----------ERROR-----------\n'

2

निम्नलिखित प्राप्त करने के लिए डिमार्क के उत्तर पर बनाया गया है, जो उपयोगी है यदि आप स्प्रिंटफ की बराबरी चाहते हैं और उम्मीद है कि किसी को मदद मिलेगी ...

def sprint(object):
    result = ''
    for i in [v for v in dir(object) if not callable(getattr(object, v)) and v[0] != '_']:
        result += '\n%s:' % i + str(getattr(object, i, ''))
    return result

0

कभी-कभी आप सार्वजनिक / निजी संस्करण के आधार पर सूची को फ़िल्टर करना चाहते हैं। उदाहरण के लिए

def pub_vars(self):
    """Gives the variable names of our instance we want to expose
    """
    return [k for k in vars(self) if not k.startswith('_')]
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.