Woher wissen Sie, wenn Sie sich die Liste der Attribute und Methoden ansehen, die in einem DIR aufgeführt sind, welche Attribute und welche Methoden sind?

StackOverflow https://stackoverflow.com/questions/880160

Frage

Ich arbeite daran, in Python zu programmieren, und konzentriere mich darauf, einen besseren Inhalt der Verwendung von Standard- und anderen Modulen zu finden. Die DIR -Funktion scheint im Interpreter wirklich mächtig zu sein, aber ich frage mich, ob mir etwas fehlt, weil ich mangelnde OOP -Hintergründe fehlt. Mit dem Buch von S.flotts beschloss ich, seine Die Klasse zu verwenden, um mehr über Syntax und Verwendung von Klassen und Instanzen zu erfahren.

Hier ist der ursprüngliche Code:

class Die(object):
''' simulate a six-sided die '''
def roll(self):
    self.value=random.randrange(1,7)
    return self.value
def getValue(self):
    return self.value

Ich habe mir das angesehen und nach dem Erstellen einiger Fälle fragte ich mich, ob das Wortwert irgendwie ein Schlüsselwort war und was die Verwendung des Wortobjekts in der Klassenerklärung tat, und so beschloss ich, die Klassendefinition in Folgendes zu ändern:

class Die():
''' simulate a six-sided die '''
def roll(self):
    self.ban=random.randrange(1,7)
    return self.ban
def getValue(self):
    return self.ban

Diese Änderung zeigte mir, dass ich das gleiche Verhalten aus meinen Instanzen bekam, aber die folgenden Methoden/Attribute fehlten in den Fällen, in denen ich Dir:

'__class__', '__delattr__', '__dict__', '__doc__', '__getattribute__',
 '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__',
_repr__', '__setattr__', '__str__', '__weakref__'

Ich habe auch herausgefunden, dass ich, als ich in einer Instanz ein Dir machte, ein zusätzliches Keyword hatte.Verbot Was ich schließlich herausfand, war ein Attribut meiner Instanz. Dies half mir zu verstehen, dass ich benutzen konnte d1.ban Zu dem Wert meiner Instanz zugreifen. Der einzige Grund, warum ich herausfinden konnte, dass dies ein Attribut war, war, dass ich tippte d1.happy und bekam ein AttributeError Das habe ich herausgefunden d1.getValue War eine Methode, die an die Sterbe verbunden war, weil mir der Dolmetscher das sagte.

Wenn ich also versuche, ein kompliziertes, aber hilfreiches Modul wie BeautifulSoup zu verwenden, wie kann ich wissen, welche der Dinge aufgelistet sind Dir (Instanz). Ich müsste das wissen, weil mir dieses Rennen gelehrt hat, dass ich mit Attributen das Ergebnis einer Methode und mit Methoden nenne, in denen ich eine Funktion auf meiner Instanz berufe.

Diese Frage ist wahrscheinlich zu wortreich, aber es hat mir sicher geholfen, den Unterschied zwischen Attributen und Methoden besser zu verstehen. Insbesondere, wenn ich mir das Ergebnis des Aufrufens von Dir in einer Instanz meiner Würfelklasse anschaue, sehe ich das

['__doc__', '__module__', 'ban', 'getValue', 'roll']

Es scheint also nützlich zu sein, anhand dieser Liste zu wissen, welche Attribute und welche Methoden sind, ohne auf Versuch und Irrtum zurückgreifen zu müssen, oder das Ergebnis zum Eintippen HasAttr (MyInstance, mutviscedAttributename).

Nachdem ich die Frage veröffentlicht habe, habe ich versucht

for each in dir(d1):
    print hasattr(d1,each)

Das sagt mir streng genommen, dass alle Methoden Attribute sind. Aber ich kann eine Methode ohne die nicht anrufen () Es scheint mir also, dass der Hasattr () irreführend ist.

War es hilfreich?

Lösung

Anstatt von: "print hasattr(d1,each)", Versuchen: "print each, type(getattr(d1,each))". Sie sollten die Ergebnisse informativ finden.

Auch anstelle von dir() Versuchen help(), was ich denke, du suchst wirklich.

Andere Tipps

Erwägen Sie, die Standardbibliothek zu verwenden inspect Modul-Es ist oft der handlichste Ansatz zur Selbstbeobachtung, das Verpacken von erheblichen Funktionen der Funktionalität (Sie könnten das von Grund auf neu implementieren, aber eine gut getestete, gut gestaltete Code ist eine gute Sache). Sehen http://docs.python.org/library/inspect.html Für alle Details, aber zum Beispiel inspect.getmembers(foo, inspect.ismethod) ist eine hervorragende Möglichkeit, alle Methoden von Foo zu erhalten (Sie werden bekommen (name, value) Paare sortiert mit Namen).

Das sagt mir streng genommen, dass alle Methoden Attribute sind. Aber ich kann eine Methode ohne die () nicht nennen, also scheint es mir, dass der Hasattr () irreführend ist.

Warum ist es irreführend? Wenn obj.ban() ist dann eine Methode obj.ban ist das entsprechende Attribut. Sie können einen solchen Code haben:

print obj.getValue()

oder

get = obj.getValue
print get()

Wenn Sie eine Liste von Methoden für ein Objekt erhalten möchten, können Sie diese Funktion versuchen. Es ist nicht perfekt, da es auch für Callable -Attribute ausgelöst wird, die keine Methoden sind, aber für 99% der Fälle sollten gut genug sein:

def methods(obj):
    attrs = (getattr(obj, n) for n in dir(obj))
    return [a for a in attrs if a.hasattr("__call__")]

Dies info Das vom Eintauchen in Python inspirierte Modul dient dem Zweck.

def info(obj, spacing=20, collapse=1, variables=False):
    '''Print methods and their doc Strings

    Takes any object'''
    if variables:
    methodList = [method for method in dir(obj)]
    else:
    methodList = [method for method in dir(obj) if callable(getattr(obj,method))]

    #print methodList


    print '\n'.join(['%s %s' %
            (method.ljust(spacing),
             " ".join(str(getattr(obj,method).__doc__).split()))
            for method in methodList])


if __name__=='__main__':
    info(list)

Es gibt eine eingebaute Methode namens Callable. Sie können es auf ein beliebiges Objekt anwenden und es wird wahr/falsch zurückgegeben, je nachdem, ob es aufgerufen werden kann. z.B

>>> def foo():
...   print "This is the only function now"
...
>>> localDictionary = dir()
>>> for item in localDictionary:
...   print repr(item) + "is callable: " + str(callable(locals()[item]))
'__builtins__'is callable: False
'__doc__'is callable: False
'__name__'is callable: False
'foo'is callable: True

Beachten Sie, dass der Aufruf der Einheimischen () ein Wörterbuch zurückgibt, das alles enthält, was in Ihrem aktuellen Bereich definiert ist. Ich habe dies getan, weil die Gegenstände aus dem Wörterbuch nur Strings sind und wir auf dem tatsächlichen Objekt aufgerufen werden müssen.

Im Idealfall sollten Sie bei Verwendung einer komplizierten Bibliothek wie BeautifulSoup ihre Dokumentation konsultieren, um zu sehen, welche Methoden jede Klasse bereitstellt. In dem seltenen Fall, in dem Sie jedoch keine leicht zugängliche Dokumentation haben, können Sie nach den folgenden Vorhandensein von Methoden prüfen.

Alle Methoden, die selbst Objekte sind, implementieren die __call__ Methode und kann mit der Methode CALLABLE () überprüft werden, die zurückgegeben wird True, wenn der von dem Wert geprüfte Wert das hat __call__ Methode.

Der folgende Code sollte funktionieren.

x = Die()
x.roll()

for attribute in dir(x) :
    print attribute, callable(getattr(x, attribute))

Der obige Code würde für alle Methoden für alle nicht abrufbaren Attribute (z. B. Datenmitglieder wie Ban) zutreffend zurückgeben. Diese Methode kehrt jedoch auch zurück True für alle Anrufobjekte (wie innere Klassen). Sie können auch überprüfen, ob der Typ des Attributs ist instancemethod

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top