it-swarm.com.de

Wie bekomme ich Instanzvariablen in Python?

Gibt es eine integrierte Methode in Python, um ein Array aller Instanzvariablen einer Klasse abzurufen? Wenn ich zum Beispiel diesen Code habe:

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

Gibt es eine Möglichkeit für mich, dies zu tun:

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

Edit: Ich hatte ursprünglich fälschlicherweise nach Klassenvariablen gefragt.

104
Chris Bunch

Jedes Objekt hat ein __dict__ Variable, die alle Variablen und ihre Werte enthält.

Versuche dies

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

Verwenden Sie vars ()

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

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

Normalerweise können Instanzattribute nicht nur für eine Klasse angegeben werden, zumindest nicht, ohne die Klasse zu instanziieren. Sie können jedoch Instanzattribute für eine Instanz oder Klassenattribute für eine Klasse erhalten. Siehe das 'inspect'-Modul. Sie können keine Liste der Instanzattribute abrufen, da Instanzen tatsächlich ein beliebiges Attribut haben können, und wie in Ihrem Beispiel besteht die normale Art, sie zu erstellen, darin, sie nur mit der Methode __init__ zuzuweisen.

Eine Ausnahme ist, wenn Ihre Klasse Slots verwendet. Hierbei handelt es sich um eine feste Liste von Attributen, die die Klasse für Instanzen zulässt. Slots werden in http://www.python.org/2.2.3/descrintro.html erklärt, aber es gibt verschiedene Fallstricke mit Slots. Sie wirken sich auf das Speicherlayout aus, sodass die Mehrfachvererbung problematisch sein kann und die Vererbung im Allgemeinen auch Steckplätze berücksichtigen muss.

14
Thomas Wouters

Sowohl die Vars () - als auch die dict-Methode funktionieren für das Beispiel, das das OP veröffentlicht hat, aber nicht für "lose" definierte Objekte wie:

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

Um alle nicht aufrufbaren Attribute zu drucken, können Sie die folgende Funktion verwenden:

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
14
dmark

Sie können auch testen, ob ein Objekt eine bestimmte Variable hat:

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

Vorschlagen

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

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

Mit anderen Worten, es umschließt im Wesentlichen nur __dict__

6
daniel

Obwohl dies keine direkte Antwort auf die OP-Frage ist, gibt es eine ziemlich nette Möglichkeit, herauszufinden, welche Variablen in einer Funktion Gültigkeitsbereich haben. Schauen Sie sich diesen Code an:

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

Das func_code-Attribut enthält alle möglichen interessanten Dinge. Es erlaubt dir coole Sachen zu machen. Hier ist ein Beispiel, wie ich das benutzt habe:

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'
5
tim.tadh

Ihr Beispiel zeigt "Instanzvariablen", nicht wirklich Klassenvariablen.

Suchen Sie in hi_obj.__class__.__dict__.items() nach den Klassenvariablen zusammen mit anderen Klassenmitgliedern wie Mitgliedsfunktionen und dem enthaltenden Modul.

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

Klassenvariablen werden von allen Instanzen der Klasse gemeinsam genutzt.

5
S.Lott

baut auf der Antwort von dmark auf, um Folgendes zu erhalten, was nützlich ist, wenn Sie die Entsprechung von sprintf wünschen und hoffentlich jemandem helfen wollen ...

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
Ethan Joffe