किसी वस्तु की सूची विशेषताएँ


329

क्या उन विशेषताओं की एक सूची को हथियाने का एक तरीका है जो एक वर्ग के उदाहरणों पर मौजूद हैं?

class new_class():
    def __init__(self, number):
        self.multi = int(number) * 2
        self.str = str(number)

a = new_class(2)
print(', '.join(a.SOMETHING))

वांछित परिणाम यह है कि "मल्टी, स्ट्र" आउटपुट होगा। मैं चाहता हूं कि यह एक स्क्रिप्ट के विभिन्न हिस्सों से वर्तमान विशेषताओं को देखें।


75
वस्तुतः पायथन में हर कोई अपनी कक्षाओं के नाम बताता है NewClass। यदि आप नामकरण सम्मेलन का उपयोग करते हैं तो आप लोगों की अपेक्षाओं को धता बता सकते हैं new_class
माइक ग्राहम

भले ही यह मानव-संवादात्मक है और इसका उपयोग प्रोग्राम के रूप में नहीं किया जा सकता है, help()फ़ंक्शन कक्षाओं, फ़ंक्शंस, बिल्डिंस, मॉड्यूल और अधिक की जानकारी प्राप्त करने में मदद करता है
ytpillai


कोई भी उत्तर 'स्वीकृत' के रूप में चिह्नित क्यों नहीं हैं?
pfabri

जवाबों:


295
>>> class new_class():
...   def __init__(self, number):
...     self.multi = int(number) * 2
...     self.str = str(number)
... 
>>> a = new_class(2)
>>> a.__dict__
{'multi': 4, 'str': '2'}
>>> a.__dict__.keys()
dict_keys(['multi', 'str'])

तुम भी मिल सकता है pprint उपयोगी।


29
तानाशाही उपयोग का मुद्दा सिर्फ r / python पर दिखा। किसी ने बताया कि var (a) .__ तानाशाही के बराबर है
David

5
यदि कोई सोच रहा है, तो यह पायथन 2.7 के साथ
बेन मोर्दकै

8
विशिष्ट होने के लिए, pprint.pprint(a.__dict__)विशेषताओं पर एक सुंदर-प्रिंट करता है।
smci

1
निश्चित रूप से यह pprintपायथन 2.6 पर काम नहीं करता है।
जॉन ग्रीन

3
ध्यान दें कि यह केवल उपयोगकर्ता-परिभाषित कक्षाओं के लिए काम करता है, अंतर्निहित या विस्तार प्रकारों के लिए नहीं।
ivan_pozdeev

173
dir(instance)
# or (same value)
instance.__dir__()
# or
instance.__dict__

फिर आप परीक्षण कर सकते हैं कि किस प्रकार के साथ है type()या यदि एक विधि है callable()


dir ने अतिभारित विशेषता प्राप्त / सेट के साथ कक्षाओं में बेहतर काम किया
ogurets

dir (उदाहरण) बहुत सारी चीजों को सूचीबद्ध करता है जिनकी आप शायद रुचि नहीं रखते हैं
jciloa

यह एकमात्र ऐसा कार्य था जो bostonस्केलेरोन से डेटासेट पर मुझे सभी उपलब्ध विशेषताओं को मिला - __dict__खाली था, जब वास्तव में 5 उपलब्ध विशेषताएँ थीं
Coruscate5


53

पिछले सभी उत्तर सही हैं, आपके पास तीन विकल्प हैं जो आप पूछ रहे हैं

  1. dir()

  2. vars()

  3. __dict__

>>> dir(a)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'multi', 'str']
>>> vars(a)
{'multi': 4, 'str': '2'}
>>> a.__dict__
{'multi': 4, 'str': '2'}

1
vars(foo)रिटर्नfoo.__dict__
बोरिस

32
>>> ', '.join(i for i in dir(a) if not i.startswith('__'))
'multi, str'

यह निश्चित रूप से कक्षा की परिभाषा में किसी भी तरीके या विशेषताओं को मुद्रित करेगा। आप बदल कर बाहर कर सकते हैं "निजी" तरीकों i.startwith('__')कोi.startwith('_')


24

निरीक्षण मॉड्यूल एक वस्तु का निरीक्षण करने के आसान तरीके प्रदान करता है:

निरीक्षण मॉड्यूल जीवित वस्तुओं के बारे में जानकारी प्राप्त करने में मदद करने के लिए कई उपयोगी कार्य प्रदान करता है जैसे मॉड्यूल, कक्षाएं, विधियों, फ़ंक्शन, ट्रेसबैक, फ़्रेम ऑब्जेक्ट और कोड ऑब्जेक्ट।


का उपयोग करके getmembers()आप अपने वर्ग की सभी विशेषताओं को उनके मूल्य के साथ देख सकते हैं। निजी या संरक्षित विशेषताओं का उपयोग करने के लिए .startswith('_')। बाहर करने के लिए तरीकों या कार्यों का उपयोग inspect.ismethod()या inspect.isfunction()

import inspect


class NewClass(object):
    def __init__(self, number):
        self.multi = int(number) * 2
        self.str = str(number)

    def func_1(self):
        pass


a = NewClass(2)

for i in inspect.getmembers(a):
    # Ignores anything starting with underscore 
    # (that is, private and protected attributes)
    if not i[0].startswith('_'):
        # Ignores methods
        if not inspect.ismethod(i[1]):
            print(i)

ध्यान दें कि पहले ismethod()के दूसरे तत्व पर प्रयोग किया जाता है iक्योंकि यह केवल एक स्ट्रिंग है (इसका नाम)।

Offtopic: वर्ग के नाम के लिए CamelCase का उपयोग करें ।


13

आप dir(your_object)विशेषताओं getattr(your_object, your_object_attr)को प्राप्त करने और मूल्यों को प्राप्त करने के लिए उपयोग कर सकते हैं

उपयोग:

for att in dir(your_object):
    print (att, getattr(your_object,att))

यह विशेष रूप से उपयोगी है यदि आपकी वस्तु में __dict__ नहीं है। अगर ऐसा नहीं है तो आप var (your_object) भी आज़मा सकते हैं


11

यह अक्सर उल्लेख किया जाता है कि आपके द्वारा उपयोग की जाने वाली विशेषताओं की एक पूरी सूची को सूचीबद्ध करने के लिए dir()। हालांकि ध्यान दें कि लोकप्रिय धारणा के विपरीत सभी विशेषताओं dir()को बाहर नहीं लाया जाता है। उदाहरण के लिए, आप देख सकते हैं कि कक्षा की सूची से गायब हो सकता है, भले ही आप इसे कक्षा से ही एक्सेस कर सकें। डॉक्स ऑन ( पायथन 2 , पायथन 3 ):__name__dir()dir()

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

निम्नलिखित की तरह एक समारोह, और अधिक पूरा हो जाता है द्वारा वापस सूची के बाद से पूर्णता की कोई गारंटी नहीं है, हालांकि dir()को लागू करने सहित कई कारकों से प्रभावित हो सकते __dir__()विधि, या अनुरूपण __getattr__()या __getattribute__()वर्ग या उसके माता-पिता में से एक पर। अधिक विवरण के लिए प्रदान किए गए लिंक देखें।

def dirmore(instance):
    visible = dir(instance)
    visible += [a for a in set(dir(type)).difference(visible)
                if hasattr(instance, a)]
    return sorted(visible)

9

आप इसके लिए क्या चाहते हैं? आपके सटीक इरादे को जाने बिना आपको सबसे अच्छा जवाब मिलना मुश्किल हो सकता है।

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

    यदि आप एक वर्ग की सामग्री को प्रदर्शित मैन्युअल गुण आप ध्यान से प्रारूप और के रूप में प्रदान के लिए एक रास्ता के लिए देख रहे हैं __str__या __repr__अपने वर्ग के लिए विधि।

  • यदि आप किसी वस्तु को समझने के लिए कि वह कैसे काम करती है, उपयोग करती है, इसके बारे में क्या सीखना है और इस तरह मौजूद है helphelp(a)आपको इसके डॉकस्ट्रिंग्स के आधार पर ऑब्जेक्ट के क्लास के बारे में एक स्वरूपित आउटपुट दिखाएगा।

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

  • कुछ हद तक रूढ़िवादी नोट पर, मौजूदा समय में पायथन 3 के लिए बहुत कम समर्थन है। यदि आप वास्तविक सॉफ़्टवेयर लिखने में रुचि रखते हैं, तो आप तीसरे पक्ष के सामान जैसे सुपी, एलएक्सएमएल, ट्विस्टेड, पीआईएल, या किसी भी वेब फ्रेमवर्क की संख्या चाहते हैं जो अभी तक पायथन 3 का समर्थन नहीं करते हैं और जल्द ही किसी भी समय की योजना नहीं बनाते हैं। 2.6 और 3.x शाखा के बीच अंतर छोटा है, लेकिन पुस्तकालय समर्थन में अंतर बहुत बड़ा है।


4
मैं सिर्फ यह बताना चाहता हूं कि पांच साल बाद (अब), मुझे विश्वास है कि आप सभी तीसरे पक्ष के मॉड्यूल हैं जो आपके समर्थन python3 का उल्लेख करते हैं। स्रोत: python3wos.appspot.com
pzkpfw

8

इसे करने का एक से अधिक तरीका है:

#! /usr/bin/env python3
#
# This demonstrates how to pick the attiributes of an object

class C(object) :

  def __init__ (self, name="q" ):
    self.q = name
    self.m = "y?"

c = C()

print ( dir(c) )

जब चलाने, इस कोड का उत्पादन:

jeffs@jeff-desktop:~/skyset$ python3 attributes.py 
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__',      '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'm', 'q']

jeffs@jeff-desktop:~/skyset$

2
यह उत्तर क्यों अस्वीकृत किया गया है? डिबगिंग उद्देश्य के लिए, dir बहुत अच्छी तरह से काम करता है!
डुनोटोटॉस

पायथन 2.7.x के साथ सुंदर काम करता है। बिल्कुल वही जो मैं चाहता था।
डेविडसन लीमा

7

कृपया अजगर शेल स्क्रिप्ट देखें, जिसे क्रम से निष्पादित किया गया है, यहां आपको अल्पविराम से अलग स्ट्रिंग प्रारूप में एक वर्ग की विशेषताएं मिलेंगी।

>>> class new_class():
...     def __init__(self, number):
...         self.multi = int(number)*2
...         self.str = str(number)
... 
>>> a = new_class(4)
>>> ",".join(a.__dict__.keys())
'str,multi'<br/>

मैं अजगर 3.4 का उपयोग कर रहा हूं


और अगर आप केवल सूची का उपयोग करना चाहते हैं a.__dict__.keys()। हालाँकि यदि आप जानना चाहते हैं कि क्या किसी वस्तु का कोई विशिष्ट गुण है जिसका आप उपयोग कर सकते हैं hasattr
berna1111

4

इन जवाबों के अलावा, मैं लगभग किसी भी मूल्य के पूरे ढांचे को उगलने के लिए एक फ़ंक्शन (अजगर 3) शामिल करूंगा। यह dirसंपत्ति के नामों की पूरी सूची स्थापित करने के लिए उपयोग करता है, फिर getattrप्रत्येक नाम के साथ उपयोग करता है । यह मूल्य के प्रत्येक सदस्य के प्रकार को प्रदर्शित करता है, और जब संभव हो तो पूरे सदस्य को भी प्रदर्शित करता है:

import json

def get_info(obj):

  type_name = type(obj).__name__
  print('Value is of type {}!'.format(type_name))
  prop_names = dir(obj)

  for prop_name in prop_names:
    prop_val = getattr(obj, prop_name)
    prop_val_type_name = type(prop_val).__name__
    print('{} has property "{}" of type "{}"'.format(type_name, prop_name, prop_val_type_name))

    try:
      val_as_str = json.dumps([ prop_val ], indent=2)[1:-1]
      print('  Here\'s the {} value: {}'.format(prop_name, val_as_str))
    except:
      pass

अब निम्नलिखित में से किसी को भी जानकारी देनी चाहिए:

get_info(None)
get_info('hello')

import numpy
get_info(numpy)
# ... etc.

वाह, यह एक मणि है!
pfabri

हाँ, यह एक जीवन रक्षक था। यह पता नहीं लगा सका कि मैं इन सूचियों को आसानी से अनपैक क्यों नहीं कर सका और यकीन है कि पर्याप्त प्रकार की संपत्ति " स्लॉट " प्रकार की है "टपल" यहाँ स्लॉट्स मान है: ["nsname", "hostmaster", "serial", "ताज़ा", "रिट्री", "एक्सपायर", "मिन्टल", "टीटीएल"]
मिक आर

3

किसी वस्तु का गुण प्राप्त करना

class new_class():
    def __init__(self, number):
    self.multi = int(number) * 2
    self.str = str(number)

new_object = new_class(2)                
print(dir(new_object))                   #total list attributes of new_object
attr_value = new_object.__dict__         
print(attr_value)                        #Dictionary of attribute and value for new_class                   

for attr in attr_value:                  #attributes on  new_class
    print(attr)

उत्पादन

['__class__', '__delattr__', '__dict__', '__dir__', '__doc__','__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'multi', 'str']

{'multi': 4, 'str': '2'}

multi
str

1

जैसा कि उपयोग करने से पहले लिखा गया है obj.__dict__सामान्य मामलों को संभाल सकता है लेकिन कुछ वर्गों में __dict__विशेषता और उपयोग नहीं होता है __slots__(ज्यादातर मेमोरी दक्षता के लिए)।

ऐसा करने के अधिक लचीला तरीके के लिए उदाहरण:

class A(object):
    __slots__ = ('x', 'y', )
    def __init__(self, x, y):
        self.x = x
        self.y = y


class B(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y


def get_object_attrs(obj):
    try:
        return obj.__dict__
    except AttributeError:
        return {attr: getattr(obj, attr) for attr in obj.__slots__}


a = A(1,2)
b = B(1,2)
assert not hasattr(a, '__dict__')

print(get_object_attrs(a))
print(get_object_attrs(b))

इस कोड का आउटपुट:

{'x': 1, 'y': 2}
{'x': 1, 'y': 2}

नोट 1:
पायथन एक गतिशील भाषा है और यह हमेशा उन वर्गों को जानना बेहतर होता है जिन्हें आप उन विशेषताओं को प्राप्त करने की कोशिश कर रहे हैं जहां से यह कोड कई मामलों को याद कर सकता है।

नोट 2:
यह कोड आउटपुट केवल उदाहरण चर का मतलब है कि वर्ग चर प्रदान नहीं किए जाते हैं। उदाहरण के लिए:

class A(object):
    url = 'http://stackoverflow.com'
    def __init__(self, path):
        self.path = path

print(A('/questions').__dict__)

कोड आउटपुट:

{'path': '/questions'}

यह कोड urlवर्ग विशेषता को प्रिंट नहीं करता है और वह वर्ग विशेषताओं को छोड़ सकता है।
कभी-कभी हमें लगता है कि एक विशेषता एक उदाहरण सदस्य है, लेकिन यह इस उदाहरण का उपयोग करके नहीं दिखाया जाएगा।


2
एक वर्ग हो सकता है __dict__ और __slots__ इसलिए, आप शायद केवल तानाशाह के बजाय दोनों को आजमाना चाहते हैं।
cz

1
  • उपयोग करना __dict__या vars काम नहीं करता क्योंकि यह याद आती है __slots__
  • का उपयोग करना __dict__और __slots__ काम नहीं करता है क्योंकि यह __slots__बेस कक्षाओं से छूट जाता है।
  • उपयोग करना dir काम नहीं करता है क्योंकि इसमें क्लास विशेषताओं, जैसे कि विधियाँ या गुण, साथ ही ऑब्जेक्ट विशेषताएँ शामिल हैं।
  • का उपयोग करने varsके बराबर है __dict__

यह मेरे पास सबसे अच्छा है:

from typing import Dict

def get_attrs( x : object ) -> Dict[str, object]:
    mro      = type( x ).mro()
    attrs    = { }
    has_dict = False
    sentinel = object()

    for klass in mro:
        for slot in getattr( klass, "__slots__", () ):
            v = getattr( x, slot, sentinel )

            if v is sentinel:
                continue

            if slot == "__dict__":
                assert not has_dict, "Multiple __dicts__?"
                attrs.update( v )
                has_dict = True
            else:
                attrs[slot] = v

    if not has_dict:
        attrs.update( getattr( x, "__dict__", { } ) )

    return attrs

आइए इस फ़ंक्शन को सरल सरल वर्ग पर लागू करें: वर्ग C: def __init __ (स्व): प्रिंट ("बनाया") i = 42 आपका कोड इस तरह के वर्ग के लिए खाली सूची क्यों देता है? (मेरा मतलब है कि अगर ओ = सी () तो get_attrs (o) खाली है) यह get_attrs ("मिस्ट्री") के लिए भी किया
ged

0
attributes_list = [attribute for attribute in dir(obj) if attribute[0].islower()]

यह बड़े अक्षर या एकल अंडरस्कोर के साथ शुरू होने वाले वर्ग विशेषता नामों के साथ काम नहीं करता है।
fviktor

0

कृपया अनुक्रम में निम्नलिखित पायथन शेल स्क्रिप्टिंग निष्पादन देखें, यह कक्षा के निर्माण से लेकर उदाहरणों के क्षेत्र नामों को निकालने तक का समाधान देगा।

>>> class Details:
...       def __init__(self,name,age):
...           self.name=name
...           self.age =age
...       def show_details(self):
...           if self.name:
...              print "Name : ",self.name
...           else:
...              print "Name : ","_"
...           if self.age:
...              if self.age>0:
...                 print "Age  : ",self.age
...              else:
...                 print "Age can't be -ve"
...           else:
...              print "Age  : ","_"
... 
>>> my_details = Details("Rishikesh",24)
>>> 
>>> print my_details
<__main__.Details instance at 0x10e2e77e8>
>>> 
>>> print my_details.name
Rishikesh
>>> print my_details.age
24
>>> 
>>> my_details.show_details()
Name :  Rishikesh
Age  :  24
>>> 
>>> person1 = Details("",34)
>>> person1.name
''
>>> person1.age
34
>>> person1.show_details
<bound method Details.show_details of <__main__.Details instance at 0x10e2e7758>>
>>> 
>>> person1.show_details()
Name :  _
Age  :  34
>>>
>>> person2 = Details("Rob Pike",0)
>>> person2.name
'Rob Pike'
>>> 
>>> person2.age
0
>>> 
>>> person2.show_details()
Name :  Rob Pike
Age  :  _
>>> 
>>> person3 = Details("Rob Pike",-45)
>>> 
>>> person3.name
'Rob Pike'
>>> 
>>> person3.age
-45
>>> 
>>> person3.show_details()
Name :  Rob Pike
Age can't be -ve
>>>
>>> person3.__dict__
{'age': -45, 'name': 'Rob Pike'}
>>>
>>> person3.__dict__.keys()
['age', 'name']
>>>
>>> person3.__dict__.values()
[-45, 'Rob Pike']
>>>

हम भी प्रत्येक attributes.visit की callablilty के लिए जाँच कर सकते हैं stackoverflow.com/questions/1398022/...
hygull

-4

__attr__ एक उदाहरण की विशेषताओं की सूची देता है।

>>> import requests
>>> r=requests.get('http://www.google.com')
>>> r.__attrs__
['_content', 'status_code', 'headers', 'url', 'history', 'encoding', 'reason', 'cookies', 'elapsed', 'request']
>>> r.url
'http://www.google.com/'
>>>

हमेशा काम नहीं करता है। इसके अलावा, आप __attr__विवरण में लिखते हैं लेकिन __attrs__कोड में उपयोग करते हैं। न तो मेरे लिए काम किया (werkzeug.datastructures.FileStorage)
जोनास
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.