पायथन में किसी ऑब्जेक्ट के गुणों की गणना कैसे करें?


133

आईसी # हम इसे प्रतिबिंब के माध्यम से करते हैं। जावास्क्रिप्ट में यह सरल है:

for(var propertyName in objectName)
    var currentPropertyValue = objectName[propertyName];

इसे पायथन में कैसे करें?



3
कृपया ध्यान दें कि यह प्रश्न एक मिथ्या नाम है। अधिकांश उत्तर सदस्यों की गणना करने के बारे में हैं । मैं गुणों की गणना करने का एक तरीका खोज रहा था , अर्थात एक वर्ग के सदस्यों से सजाया गया था @property
टॉमस गैंडर

जवाबों:


153
for property, value in vars(theObject).iteritems():
    print property, ": ", value

ध्यान रखें कि कुछ दुर्लभ मामलों में __slots__संपत्ति होती है, ऐसी कक्षाएं अक्सर नहीं होती हैं __dict__


1
अब मूल्य कैसे बदलें? जावास्क्रिप्ट में आप कर सकते हैं: वस्तु [संपत्ति] = newValue। इसे पायथन में कैसे करें?
Jader Dias

39
इसके बजाय setattr () का उपयोग करें।
नेल्सन

1
@ नेल्सन क्या आप बता सकते हैं कि बेहतर विकल्प क्यों है? क्या यह सिर्फ छोटा है, या अतिरिक्त विचार हैं?
WhyNotHugo

8
@ ह्यूगो: पहला क्योंकि यह "पाइथोनिक" है, दूसरे शब्दों में जो वाक्यविन्यास समुदाय का एक बड़ा हिस्सा देखने की उम्मीद कर रहा है। अन्य वाक्यविन्यास संभवतः आपके कोड को पढ़ने वाले किसी व्यक्ति को अनावश्यक रूप से रोक देगा। दूसरा, कुछ प्रकार सेटर को लागू करते हैं __setattr__()। शब्दकोश पर सीधे मान सेट करना ऑब्जेक्ट के सेटर (और / या उसके माता-पिता) को बायपास करता है। यह अजगर में काफी आम है कि विशेषता सेटिंग (जैसे स्वच्छता) के दौरान आंख से मिलने की तुलना में अधिक चीजें पृष्ठभूमि में हो रही हैं, setattr()यह सुनिश्चित करने के लिए कि आप याद नहीं करते हैं, या उन्हें अपने आप को संभालने के लिए मजबूर किया जाता है।
माइकल एको

3
@ हाय-एंजेल जो काम करता है । हालांकि, जो काम नहीं कर रहा है, वह पूर्व धारणाओं और मान्यताओं का नक्षत्र है जो आपके पास पायथन में गतिशील वस्तु सदस्यों बनाम स्थिति है। vars()केवल स्थैतिक सदस्यों (यानी, वस्तु की विशेषताओं और विधियों को उस वस्तु के साथ पंजीकृत __dict__) लौटाता है । यह गतिशील सदस्यों (यानी, वस्तु की विशेषताओं और विधियों को गतिशील रूप से उस वस्तु की विधि या इसी तरह के जादू से परिभाषित नहीं करता है) को वापस नहीं करता है । सभी संभावना में, अपने वांछित संपत्ति गतिशील रूप में परिभाषित किया गया है और इसलिए है नहीं करने के लिए उपलब्ध या । __getattr__()file.ImplementationNamevars()dir()
सेसिल करी

69

देख लो inspect.getmembers(object[, predicate])

किसी वस्तु के सभी सदस्यों को नाम के अनुसार क्रमबद्ध (नाम, मान) जोड़े की सूची में लौटाएं। यदि वैकल्पिक विधेय तर्क की आपूर्ति की जाती है, तो केवल वे सदस्य जिनके लिए विधेय लौटाता है एक सही मूल्य शामिल होता है।

>>> [name for name,thing in inspect.getmembers([])]
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', 
'__delslice__',    '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', 
'__getitem__', '__getslice__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__iter__', 
'__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__','__reduce_ex__', 
'__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__setslice__', 
'__sizeof__', '__str__', '__subclasshook__', 'append', 'count', 'extend', 'index', 
'insert', 'pop', 'remove', 'reverse', 'sort']
>>> 

हाँ, यह उत्तर बहुत अच्छा है; इस मॉड्यूल का उपयोग पहले कभी नहीं किया गया। getmembers () सिर्फ dir (ऑब्जेक्ट), btw के परिणामों को चलाकर कार्यान्वित किया जाता है।
नेल्सन

क्या आप विस्तृत कर सकते हैं कि यह तानाशाही तक पहुँचने से बेहतर क्यों है ? पाइथन प्रलेखन सहायक से कम है, खासकर क्योंकि आमतौर पर यह शब्द का उपयोग करता attributesहै members(क्या दोनों के बीच कोई अंतर है)? वे इसे सुसंगत बनाने के लिए अजगर 3.0 में नाम तय कर सकते थे।
nikow

उफ़, मतलब __dict__, सॉरी।
nikow

4
@ मिचौनी: आंतरिक विवरण बदलने पर भी काम करते रहने की गारंटी है।
जॉर्ज स्कोली 21

3
@NicholasKnight (ए) ज्यादातर ( डायग्नोस्टिक क्लास एट्रिब्यूट्स और मेटाक्लस विशेषताओं सहित ) (ए ) के साइड बेनिफिट्स के साथ inspect.getmembers()लपेटता है और बी प्रेडिकेटेट से मेल नहीं खाने वाले सदस्यों को छोड़कर । हाँ, ठीक है? सामान्य रूप से सभी संभावित ऑब्जेक्ट प्रकारों का समर्थन करने वाले तीसरे पक्ष के पुस्तकालयों के लिए उपयुक्त है। मानक उपयोग के मामलों के लिए, हालांकि, बिल्कुल पर्याप्त है। dir() inspect.getmembers()dir()
सेसिल करी

66

dir()सरल तरीका है। यहाँ देखें:

गाइड टू पाइथन इंट्रोस्पेक्शन


2
पायथन डॉक्स से नोट करने के लिए कुछ, क्योंकि dir () को मुख्य रूप से एक इंटरैक्टिव प्रांप्ट पर उपयोग करने के लिए एक सुविधा के रूप में आपूर्ति की जाती है, यह नामों की एक दिलचस्प सेट की आपूर्ति करने की कोशिश करता है जितना कि यह एक कठोर या लगातार परिभाषित नामों की आपूर्ति करने की कोशिश करता है, और इसका विस्तृत व्यवहार रिलीज़ के दौरान बदल सकता है। उदाहरण के लिए, मेटाक्लास विशेषताएँ परिणाम सूची में नहीं होती हैं जब तर्क एक वर्ग होता है।
स्काइलर

1
यह उत्तर क्ली पर स्क्रैच काम करते समय सबसे अच्छा है।

15 साल का अजगर (पूर्णकालिक नौकरी कभी नहीं) और मैं अभी भी dir()आपको धन्यवाद देना भूल गया हूं।
अभिषेक दुजारी

14

__dict__ऑब्जेक्ट की संपत्ति इसके सभी अन्य परिभाषित गुणों का एक शब्दकोश है। ध्यान दें कि पायथन कक्षाएं गेटअटर को ओवरराइड कर सकती हैं और ऐसी चीजें बना सकती हैं जो गुणों की तरह दिखती हैं लेकिन अंदर नहीं हैं __dict__। अंतर्निहित कार्य भी हैं vars()और dir()जो सूक्ष्म तरीकों से भिन्न हैं। और कुछ असामान्य कक्षाओं में __slots__बदल सकता है __dict__

पाइथन में ऑब्जेक्ट्स जटिल हैं। __dict__प्रतिबिंब-शैली प्रोग्रामिंग के लिए शुरू करने के लिए सही जगह है। dir()यदि आप एक इंटरैक्टिव शेल में चारों ओर हैक कर रहे हैं, तो शुरू करने के लिए जगह है।


print vars.__doc__इंगित करता है कि With an argument, equivalent to object.__dict__इसलिए सूक्ष्म अंतर क्या होगा?
sancho.s ReinstateMonicaCellio


10

यदि आप सभी गुणों के प्रतिबिंब की तलाश कर रहे हैं, तो ऊपर दिए गए उत्तर बहुत अच्छे हैं।

यदि आप केवल एक शब्दकोष (जो कि पायथन में एक 'ऑब्जेक्ट' से अलग है) की कुंजियाँ प्राप्त करना चाहते हैं, तो उपयोग करें

my_dict.keys()

my_dict = {'abc': {}, 'def': 12, 'ghi': 'string' }
my_dict.keys() 
> ['abc', 'def', 'ghi']

1
हालांकि यह मेरा जवाब है, मुझे नहीं लगता कि यह स्वीकृत उत्तर होना चाहिए: एक वस्तु की कुंजी एक वर्ग के ऑब्जेक्ट उदाहरण की संपत्ति से अलग होती है। वे अलग-अलग तरीके से obj['key']पहुंचते हैं ( बनाम obj.property) और सवाल ऑब्जेक्ट प्रॉपर्टीज के बारे में था। मैंने अपना जवाब यहां दिया क्योंकि दोनों के बीच आसान भ्रम है।
श्रीमती

मैं वास्तव में इस उत्तर को हटाने का सुझाव दूंगा।
Ente

जैसा कि ऊपर कहा गया है, उदाहरण के लिए जावास्क्रिप्ट या C # से आने वाले लोग शब्दावली से आसानी से भ्रमित हो जाते हैं क्योंकि उन 2 अवधारणाओं के बीच कोई अंतर नहीं है। अजगर को सीखने वाले लोग और चाबियाँ एक्सेस करने की कोशिश कर रहे हैं, 'गुण' की खोज करने और यहां समाप्त होने की बहुत संभावना है, इसलिए मुझे लगता है कि यह संबंधित है।

और आप सही हैं, लेकिन इस बिंदु को याद करते हैं: अन्य भाषाओं में (जेएस को लें) वस्तु और शब्दकोश में कोई अंतर नहीं है। ओ पी # सवाल पूछने से आता है। यह जवाब, हालांकि गलत है, 11 अपवोट मिला है, इस बात का सबूत है कि जो लोग यहां उतरते हैं, वे इसे उपयोगी पाते हैं, भले ही यह तकनीकी रूप से सही जवाब नहीं है (जैसा कि मैं इंगित करता हूं) जब इसे सख्त अजगर लिंगो में देखते हैं। मैं इसे और भी अधिक स्पष्ट करने के लिए संपादित करूँगा।
MrE

5

यह अन्य उत्तरों द्वारा पूरी तरह से कवर किया गया है, लेकिन मैं इसे स्पष्ट कर दूंगा। एक ऑब्जेक्ट में क्लास एट्रिब्यूट्स और स्टैटिक और डायनेमिक इंस्टेंस विशेषताएँ हो सकती हैं।

class foo:
    classy = 1
    @property
    def dyno(self):
        return 1
    def __init__(self):
        self.stasis = 2

    def fx(self):
        return 3

stasisस्थिर है, dynoगतिशील है (cf. संपत्ति डेकोरेटर) और classyएक वर्ग विशेषता है। यदि हम बस करते हैं __dict__या varsहम केवल स्थैतिक प्राप्त करेंगे।

o = foo()
print(o.__dict__) #{'stasis': 2}
print(vars(o)) #{'stasis': 2}

इसलिए अगर हम चाहते हैं कि दूसरों __dict__को सब कुछ (और अधिक) मिलेगा। इसमें जादू के तरीके और विशेषताएँ और सामान्य बाध्य विधियाँ शामिल हैं। तो उन लोगों से बचने की सुविधा देता है:

d = {k: getattr(o, k, '') for k in o.__dir__() if k[:2] != '__' and type(getattr(o, k, '')).__name__ != 'method'}
print(d) #{'stasis': 2, 'classy': 1, 'dyno': 1}

typeएक संपत्ति सजाया विधि (एक डायनामिक विशेषता) के साथ कहा जाता है आप दिए गए मान के प्रकार देते हैं, नहीं होगा method। यह साबित करने के लिए आइए जोंस इसे कठोर करें:

import json
print(json.dumps(d)) #{"stasis": 2, "classy": 1, "dyno": 1}

अगर यह एक तरीका होता तो यह दुर्घटनाग्रस्त हो जाता।

टी एल; डॉ। कॉल करने का प्रयास करेंextravar = lambda o: {k: getattr(o, k, '') for k in o.__dir__() if k[:2] != '__' and type(getattr(o, k, '')).__name__ != 'method'}तीनों के लिए , लेकिन न तो तरीके और न ही जादू।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.