2017-03-06 2 views
0

Ich verwende eine Klasse von einem Client (ich habe keinen Zugriff auf den Objektcode), und ich versuche zu überprüfen, ob ein Objekt ein Attribut hat. Das Attribut selbst ist nur schreiben, so dass die hasattr versagt:Python: Auf schreib nur attr einer Klasse

>>> driver.console.con.input = 'm' 
>>> hasattr(driver.console.con, 'input') 
False 
>>> simics> @driver.console.con.input 
Traceback (most recent call last): 
File "<string>", line 1, in <module> 
Attribute: Failed converting 'input' attribute in object 
'driver.console.con' to Python: input attribute in driver.console.con 
object: not readable. 

Gibt es eine andere Art und Weise zu überprüfen, ob ein Attribut vorhanden ist?

+0

Denken Sie an EAFP, könnten Sie es in einen 'try' Block und außer' AttributeError' wickeln, wenn es nicht existiert? – RichSmith

+0

Wird "nicht lesbar" angezeigt, wenn Sie versuchen, auf ein Attribut zuzugreifen, das Sie nicht erstellt haben? Wenn dies der Fall ist, können Sie einfach überprüfen, ob die Nachricht des Ausnahmeobjekts 'nicht lesbar' enthält. – Blender

+0

@RichSmith Das ist derzeit die Art und Weise, wie ich daran dachte, das Problem anzugreifen. Ich frage mich auch, was dahinter steckt. –

Antwort

3

Sie scheinen eine Art von nativen Code-Proxy zu haben, die Python zu einer Erweiterung überbrückt, und es bricht eher normalen Python Konventionen

Es gibt zwei Möglichkeiten:

  1. Das driver.console.con Objekt hat eine Namensbereich, der Attribute wie descriptors implementiert, und der input Deskriptor hat nur eine __set__ method (und möglicherweise eine __delete__ method). In diesem Fall sucht der Descriptor:

    if 'input' in vars(type(driver.console.con)): 
        # there is an `input` name in the namespace 
        attr = vars(type(driver.console.con))['input'] 
        if hasattr(attr, '__set__'): 
         # can be set 
         ... 
    

    Hier ist der vars() function ruft den Namespace für die Klasse für driver.console.con verwendet.

  2. Der Proxy verwendet __getattr__ (oder sogar __getattribute__) und __setattr__ hooks, um beliebige Attribute zu behandeln. Sie haben hier kein Glück, Sie können nicht erkennen, welche der beiden Methoden die Methode außerhalb von hasattr() unterstützt und versuchen, das Attribut direkt festzulegen. Verwenden Sie try...except Bewachungs:

    try: 
        driver.console.con.input = 'something' 
    except Attribute: # exactly what exception object does this throw? 
        # can't be set, not a writable attribute 
        pass 
    

    Sie können einen Debugger verwenden oder print() Anweisung, genau herauszufinden, was Ausnahme ausgelöst wird (verwenden Sie einen try...except Exception as ex: Block zu erfassen alle Ausnahmen dann ex inspizieren); In der Traceback in Ihrer Frage sieht die Ausnahmebedingungsnachricht am Ende entschieden nicht standardgemäß aus. Dieses Projekt sollte wirklich einen AttributeError an diesem Punkt auslösen.

die eher benutzerdefinierte Ausnahme gegeben wird geworfen, mein Geld ist auf Option 2 (aber die Option 1 ist immer noch eine Möglichkeit, wenn die __get__ Methode auf dem Descriptor die Ausnahme auslöst).

+0

Danke! Ich dachte an den Versuch ... außer Ansatz, aber Ihre Antwort lieferte einige zusätzliche Details von unter der Haube. Danke für die ausführliche Antwort! –

Verwandte Themen