2010-10-14 7 views
6

Ho una classe Foo con un metodo isValid. Quindi ho una barra dei metodi() che riceve un oggetto Foo e il cui comportamento dipende dal fatto che sia valido o meno.Qual è il tipo di pitone più generale a cui posso aggiungere attributi?

Per verificare ciò, volevo passare un oggetto alla barra il cui metodo isValid restituisce sempre False. Per altri motivi, non posso creare un oggetto di Foo al momento del test, quindi avevo bisogno di un oggetto per simularlo. Quello che ho pensato inizialmente è stato creare l'oggetto più generale e aggiungere l'attributo è Valido per esso, per usarlo come Foo. Ma che non ha funzionato del tutto:

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

ho scoperto oggetto non ha un __dict__, quindi non è possibile aggiungere attributi ad esso. A questo punto, la soluzione che sto usando è la creazione di un tipo al volo per questo scopo e quindi la creazione di un oggetto di quel tipo:

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

Ma questo sembra troppo a lungo un colpo. Ci deve essere un tipo generale facilmente disponibile che potrei usare per questo scopo, ma quale?

risposta

6

hai l'idea giusta ma puoi renderla più generale. In entrambi i

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

o

class tmptype(object): 
    pass 

allora si può solo fare

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

come si voleva fare con object. In questo modo, puoi utilizzare la stessa classe per tutte le tue esigenze dinamiche e di patch-monky.

+0

Beh, è ​​praticamente la stessa cosa distribuita su più righe e con una nuova classe di stile. Ma la mia domanda persiste ancora: non esiste un tipo generalmente prontamente disponibile per raggiungere lo stesso scopo? Qualcosa come oggetto con un __dict__? Devo davvero creare un tipo solo per questo? – ricab

+0

@ricab: ecco un rifiuto dell'idea che ho appena ottenuto su google. Potresti riuscire a trovarne altri. http://mail.python.org/pipermail/python-bugs-list/2007-January/036866.html – aaronasterling

+0

Oh, ok, quindi non esiste un tipo simile. Anche se probabilmente mi mancava solo ... Grazie – ricab

1

perché devi renderlo complesso? Penso che il modo più semplice (e il modo in cui 'standard') è quello di fare

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

inoltre, l'uso di lambda non è buona in questo contesto ... date un'occhiata a questo: http://python-history.blogspot.com/2009/04/origins-of-pythons-functional-features.html è di il BDFL

e così via ...

+0

Perché non voglio distrarre il lettore con classi aggiuntive il cui utilizzo potrebbe averlo ostacolato e per il quale potrebbe dover cercare.Inoltre, poiché in questo modo la definizione del tipo è nell'unico luogo, viene creato il suo unico oggetto, per un unico scopo che puoi trovare subito. La definizione è dove viene utilizzata, che consente al test di essere autonomo. Quando vedi l'oggetto, vedi la definizione del tipo e quando vedi la definizione del tipo, conosci il suo unico scopo. Lo scopo sia dell'oggetto che del tipo sono chiari senza dover cercare altrove. – ricab

+0

A proposito, ho letto l'articolo e non capisco come segue che l'uso di lambda non è buono nel contesto ... – ricab

+0

so che è per un singolo scopo e così via ... ma non è il modo giusto per farlo, a mio parere ... posso scrivere provare: a.next() eccetto StopIterationError: passare intead di x in a: #pass ma non è il modo corretto ... lo so in alcuni casi puoi usarlo, ma perché dovresti farlo? a mio parere, dico ... l'articolo parlava dell'uso di lambda, ed è scritto che lambda non dovrebbe essere usato al posto di un normale 'def', ma solo quando python richiede un'espressione e non un'affermazione. ..so, puoi farlo, ma non sottolineo che è il giusto approccio al problema ... – Ant

Problemi correlati