Attributen van een object weergeven

Is er een manier om een lijst te krijgen met attributen die bestaan op instanties van een klasse?

class new_class():
    def __init__(self, number):
        self.multi = int(number) * 2
        self.str = str(number)
a = new_class(2)
print(', '.join(a.SOMETHING))

Het gewenste resultaat is dat “multi, str” wordt uitgevoerd. Ik wil dat dit de huidige attributen van verschillende delen van een script kan zien.


Antwoord 1, autoriteit 100%

>>> 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'])

Misschien vindt u pprintook nuttig.


Antwoord 2, autoriteit 52%

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

Vervolgens kun je testen welk type is met type()of of het een methode is met callable().


Antwoord 3, autoriteit 29%

Alle eerdere antwoorden zijn correct, je hebt drie opties voor wat je vraagt

  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'}

Antwoord 4, autoriteit 24%

vars(obj)geeft de attributen van een object terug.


Antwoord 5, autoriteit 10%

Inspecteermodule:

De inspectie-module biedt verschillende handige functies om u te helpen
informatie over levende objecten zoals modules, klassen, methoden,
functies, tracebacks, frame-objecten en code-objecten.


Met getmembers()kun je alle attributen van je klas zien, samen met hun waarde. Gebruik .startswith('_')om privé- of beschermde kenmerken uit te sluiten. Gebruik inspect.ismethod()of inspect.isfunction()om methoden of functies uit te sluiten.

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)

Merk op dat ismethod()wordt gebruikt op het tweede element van i, aangezien het eerste gewoon een string is (de naam).

Offtopic: gebruik CamelCasevoor de les namen.


Antwoord 6, autoriteit 9%

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

Hiermee worden natuurlijk alle methoden of attributen in de klassedefinitie afgedrukt. U kunt “private” methoden uitsluiten door i.startwith('__')te wijzigen in i.startwith('_')


Antwoord 7, autoriteit 5%

Je kunt dir(your_object)gebruiken om de attributen te krijgen en getattr(your_object, your_object_attr)om de waarden te krijgen

gebruik:

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

Dit is vooral handig als uw object geen __dict__ heeft. Als dat niet het geval is, kun je var(your_object) ook proberen


Antwoord 8, autoriteit 3%

Er wordt vaak gezegd dat je dir()moet gebruiken om een volledige lijst met attributen weer te geven. Merk echter op dat, in tegenstelling tot wat vaak wordt gedacht, dir()niet alleattributen naar voren haalt. U merkt bijvoorbeeld misschien dat __name__mogelijk ontbreekt in de dir()-lijst van een klasse, hoewel u er toegang toe hebt vanuit de klasse zelf. Uit het document op dir()(Python 2, Python 3):

Omdat dir() voornamelijk wordt geleverd als gemak voor gebruik op een
interactieve prompt, het probeert een interessante reeks namen te leveren
meer dan dat het een rigoureus of consistent gedefinieerde set probeert te leveren
van namen, en het gedetailleerde gedrag ervan kan veranderen tussen releases. Voor
Metaclass-attributen staan bijvoorbeeld niet in de resultatenlijst als de
argument is een klasse.

Een functie zoals de volgende is meestal completer, hoewel er geen garantie voor volledigheid is, aangezien de lijst die wordt geretourneerd door dir()door vele factoren kan worden beïnvloed, waaronder het implementeren van de __dir__()-methode, of het aanpassen van __getattr__()of __getattribute__()op de klas of een van zijn ouders. Zie verstrekte links voor meer details.

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

Antwoord 9, autoriteit 2%

Waarvoor wil je dit? Het kan moeilijk zijn om u het beste antwoord te geven zonder uw exacte bedoeling te kennen.

  • Het is bijna altijd beter om dit handmatig te doen als je een instantie van je klasse op een specifieke manier wilt weergeven. Dit bevat precies wat je wilt en niet wat je niet wilt, en de volgorde zal voorspelbaar zijn.

    Als u op zoek bent naar een manier om de inhoud van een klasse weer te geven, formatteert u de kenmerken die u belangrijk vindt handmatig en geeft u deze op als de methode __str__of __repr__voor uw klas.

  • Als je wilt weten welke methoden en dergelijke er zijn om een object te laten begrijpen hoe het werkt, gebruik dan help. help(a)zal je een geformatteerde output tonen over de klasse van het object op basis van zijn docstrings.

  • dirbestaat voor het programmatisch ophalen van alle attributen van een object. (Toegang tot __dict__doet iets dat ik als hetzelfde zou groeperen, maar dat ik zelf niet zou gebruiken.) Dit kan echter niet de dingen bevatten die je wilt en het kan dingen bevatten die je niet wilt. Het is onbetrouwbaar en mensen denken dat ze het veel vaker willen dan ze willen.

  • Op een enigszins orthogonale noot is er momenteel zeer weinig ondersteuning voor Python 3. Als je geïnteresseerd bent in het schrijven van echte software, wil je dingen van derden, zoals numpy, lxml, Twisted, PIL of een willekeurig aantal webframeworks die Python 3 nog niet ondersteunen en daar ook geen plannen voor hebben. De verschillen tussen 2.6 en de 3.x branch zijn klein, maar het verschil in bibliotheekondersteuning is enorm.


Antwoord 10, autoriteit 2%

Er is meer dan één manier om dit te doen:

#! /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) )

Wanneer uitgevoerd, produceert deze code:

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$

Antwoord 11, autoriteit 2%

Bekijk het python-shellscript dat in volgorde is uitgevoerd, hier krijgt u de kenmerken van een klasse in tekenreeksindeling, gescheiden door komma’s.

>>> 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/>

Ik gebruik python 3.4


Antwoord 12, autoriteit 2%

In aanvulling op deze antwoorden, zal ik een functie (python 3) toevoegen voor het uitspugen van vrijwel de volledige structuur van elke waarde. Het gebruikt dirom de volledige lijst met eigenschapsnamen op te stellen en gebruikt vervolgens getattrbij elke naam. Het toont het type van elk lid van de waarde, en indien mogelijk ook het hele lid:

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

Nu zou een van de volgende dingen inzicht moeten geven:

get_info(None)
get_info('hello')
import numpy
get_info(numpy)
# ... etc.

Antwoord 13

Krijg attributen van een object

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)

Uitvoer

['__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

Antwoord 14

Zoals eerder geschreven, kan het gebruik van obj.__dict__veelvoorkomende gevallen aan, maar sommige klassen hebben niet het kenmerk __dict__en gebruiken __slots__(meestal voor geheugenefficiëntie).

voorbeeld voor een meer veerkrachtige manier om dit te doen:

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))

Uitgang van deze code:

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

noot1:
Python is een dynamische taal en het is altijd beter, het kennen van de klassen die u probeert de kenmerken van te halen, omdat zelfs deze code sommige gevallen kan missen.

note2:
Deze code geeft alleen toezichtsvariabelen uit die betekenisvariabelen betekent, niet aanwezig. Bijvoorbeeld:

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

Code-uitgangen:

{'path': '/questions'}

Deze code drukt de urlClass Attribuut niet af en kan het Attributen van Wanted Wanting weglaten.
Soms kunnen we denken dat een attribuut een instantie-lid is, maar het is niet en zal niet worden getoond met behulp van dit voorbeeld.


Antwoord 15

Bekijk de volgende uitvoering van Python-shellscripts in volgorde, het geeft de oplossing van het maken van een klasse tot het extraheren van de veldnamen van instanties.

>>> 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']
>>>

16

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

17

__attrs__geeft de lijst met kenmerken van een exemplaar.

>>> 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/'
>>>

Other episodes