2010-10-14 3 views
6

Ich habe eine Klasse Foo mit einer Methode isValid. Dann habe ich eine Methode bar(), die ein Foo-Objekt empfängt und dessen Verhalten davon abhängt, ob es gültig ist oder nicht.Was ist der allgemeinste Python-Typ, dem ich Attribute hinzufügen kann?

Um dies zu testen, wollte ich einige Objekte an Bar übergeben, deren IsValid-Methode immer False zurückgibt. Aus anderen Gründen kann ich zum Zeitpunkt des Tests kein Objekt von Foo erstellen, also brauchte ich ein Objekt, um es zu fälschen. Ich dachte zuerst daran, das allgemeinste Objekt zu erstellen und das Attribut isValid hinzuzufügen, um es als Foo zu verwenden. Aber das hat nicht ganz funktioniert:

>>> foo = object() 
>>> foo.isValid = lambda : False 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
AttributeError: 'object' object has no attribute 'isValid' 

fand ich heraus Objekt keine __dict__, so kann man nicht Attribute hinzufügen. An diesem Punkt wird die Abhilfe, die ich verwende, die Schaffung eine Art on the fly zu diesem Zweck und dann ein Objekt dieser Art zu schaffen:

>>> tmptype = type('tmptype',(), {'isValid' : lambda self : False}) 
>>> x = tmptype() 
>>> x.isValid() 
False 

Aber das scheint zu lange einen Schuss. Es muss einen leicht verfügbaren allgemeinen Typ geben, den ich für diesen Zweck verwenden könnte, aber welcher?

Antwort

6

Sie haben die richtige Idee, aber Sie können es allgemeiner machen. Entweder

tmptype = type('tmptype', (object,) {}) 

oder

class tmptype(object): 
    pass 

Dann können Sie einfach tun

foo = tmptype() 
foo.is_valid = lambda: False 

wie Sie mit object tun wollte. Auf diese Weise können Sie dieselbe Klasse für alle Ihre dynamischen, monkey-patchen-Anforderungen verwenden.

+0

Nun, das ist im Grunde das Gleiche, das sich auf mehr Zeilen und mit einer neuen Stilklasse verteilt. Aber meine Frage besteht immer noch: Gibt es nicht einen allgemein verfügbaren Typ, um den gleichen Zweck zu erreichen? Etwas wie ein Objekt mit einem __dict__? Muss ich wirklich einen Typ nur dafür erstellen? – ricab

+0

@ricab: Hier ist eine Ablehnung der Idee, die ich gerade von Google gezogen habe. Sie können möglicherweise andere finden. http://mail.python.org/pipermail/python-bugs-list/2007-January/036866.html – aaronasterling

+0

Oh, ok, also gibt es keinen solchen Typ. Ich habe es wahrscheinlich nur vermisst ... Danke – ricab

1

Warum müssen Sie es komplex machen müssen? Ich denke, die einfachste Art und Weise (und die ‚Standard‘ Art und Weise)

class FakeFoo(object): 
    def is_valid(): 
     return False 

außer zu tun ist, ist die Verwendung von Lambda in diesem Zusammenhang nicht gut ... einen Blick auf diesem: http://python-history.blogspot.com/2009/04/origins-of-pythons-functional-features.html ist durch der BDFL

und so weiter ...

+0

Weil ich den Leser nicht mit zusätzlichen Klassen ablenken will, deren Anwendungen ihn vielleicht verblüffen und nach denen er suchen müsste.Auch weil auf diese Weise die Definition des Typs an der einzigen Stelle ist, an der das einzige Objekt erstellt wird, können Sie für einen einzelnen Zweck sofort finden. Die Definition ist, wo es verwendet wird, wodurch der Test in sich geschlossen werden kann. Wenn Sie das Objekt sehen, sehen Sie die Typdefinition, und wenn Sie die Typdefinition sehen, kennen Sie dessen einzigen Zweck. Der Zweck von sowohl dem Objekt als auch dem Typ ist klar, ohne an anderer Stelle nachsehen zu müssen. – ricab

+0

By the way, ich lese den Artikel und ich verstehe nicht, wie folgt, dass die Verwendung von Lambda ist nicht gut in dem Kontext ... – ricab

+0

Ich weiß, es ist für einen einzigen Zweck und so weiter ... aber es ist nicht der richtige Weg, um das zu tun, meiner Meinung nach ... Ich kann schreiben versuchen: a.next() außer StopIterationError: Pass intead von für x in a: #pass aber es ist nicht der richtige Weg ... ich weiß in einigen Fällen Sie können es benutzen, aber warum sollten Sie das tun? Meiner Meinung nach, ich sage ... der Artikel war über die Verwendung von Lambda, und es ist geschrieben, dass Lambda nicht anstelle eines normalen 'def' verwendet werden soll, aber nur wenn Python einen Ausdruck und keine Aussage benötigt. ..so können Sie das tun, aber ich nicht dünn k es ist der richtige Ansatz für das Problem ... – Ant

Verwandte Themen