2010-04-08 15 views
47

È possibile avere un incarico in una condizione?Possiamo avere un incarico in una condizione?

Per es.

if (a=some_func()): 
    # Use a 
+5

-1: Trivial rispondere da soli. Duplicato: http://stackoverflow.com/questions/1663995/python-variable-assignment-and-if-statement –

+1

@ S.Lott Non è così banale da sapere perché, se non fosse per alcune delle risposte che descrivono questo Qui. –

risposta

66

Perché non provarlo?

>>> def some_func(): 
... return 2 
... 
>>> a = 2 
>>> if (a = some_func()): 
    File "<stdin>", line 1 
    if (a = some_func()): 
     ^
SyntaxError: invalid syntax 
>>> 

Quindi, no.

+17

questo è proibito intenzionalmente come Guido, dittatore pitone benevolo, li trova inutili e più confusi che utili. È lo stesso motivo per cui non ci sono operatori post-incremento o pre-incremento (++). –

+4

ha permesso l'aggiunta di * aumentata assigment * in 2.0 perché 'x = x + 1' richiede un tempo di ricerca aggiuntivo mentre' x + = 1' è un po 'più veloce, ma sono sicuro che non gli piaceva nemmeno fare * * tanto. :-) – wescpy

4

No. L'assegnazione in Python è un'istruzione, non un'espressione.

+0

E Guido non l'avrebbe in nessun altro modo. –

+0

@MarkRansom Tutti saluta Guido. * Giusto * .. sospiro. – javadba

+0

@javadba il ragazzo ha avuto ragione molto più spesso di quanto abbia sbagliato. Apprezzo che avere una sola persona responsabile della visione porti a una strategia molto più coerente rispetto alla progettazione da parte del comitato; Posso confrontare e contrastare con C++ che è il mio pane e burro principale. –

33

No, il BDFL non ha così caratteristica.

Da dove mi siedo, Guido van Rossum, "Benevolent Dictator For Life", ha lottato duramente per mantenere Python il più semplice possibile. Possiamo cavillare con alcune delle decisioni che ha preso - avrei preferito ha detto "No" più spesso, ma il fatto che non ci sia stato un comitato che progettava Python, ma invece un "comitato consultivo" fidato, basato in gran parte sul merito, che filtra attraverso la sensibilità dello stilista , ha prodotto un inferno di bella lingua, IMHO

+3

Semplice? Questa funzione potrebbe semplificare un po 'del mio codice perché avrebbe potuto renderlo più compatto e quindi più leggibile. Ora ho bisogno di due linee in cui ne avevo bisogno. Non ho mai capito perché Python ha rifiutato le funzionalità di altri linguaggi di programmazione per molti anni (e spesso per una buona ragione). Soprattutto questa caratteristica di cui stiamo parlando è molto, molto utile. –

11

Non direttamente, per this old recipe of mine - ma come dice la ricetta è facile costruire l'equivalente semantico, ad esempio se è necessario eseguire la traslitterazione direttamente da un algoritmo di riferimento codificato in C (prima di rifasare a più-idiomatici Python, di cour se ;-). Vale a dire:

class DataHolder(object): 
    def __init__(self, value=None): self.value = value 
    def set(self, value): self.value = value; return value 
    def get(self): return self.value 

data = DataHolder() 

while data.set(somefunc()): 
    a = data.get() 
    # use a 

BTW, una forma Pythonic molto idiomatica per il vostro caso specifico, se si sa esattamente quale valore falsish somefunc può restituire quando non restituisce un valore falsish (ad es 0), è

for a in iter(somefunc, 0): 
    # use a 

quindi in questo caso specifico il refactoring sarebbe piuttosto semplice ;-).

Se il reso può essere qualsiasi tipo di valore falsi (0, None, '', ...), Una possibilità è:

import itertools 

for a in itertools.takewhile(lambda x: x, iter(somefunc, object())): 
    # use a 

ma si potrebbe preferire un semplice generatore personalizzato:

def getwhile(func, *a, **k): 
    while True: 
     x = func(*a, **k) 
     if not x: break 
     yield x 

for a in getwhile(somefunc): 
    # use a 
1

Uno dei motivi per cui le assegnazioni sono illegali in condizioni è che è più facile fare un errore e assegnare Vero o False:

some_variable = 5 

# This does not work 
# if True = some_variable: 
# do_something() 

# This only works in Python 2.x 
True = some_variable 

print True # returns 5 

In Python 3 Vero e Falso sono parole chiave, quindi nessun rischio più.

+1

In [161]: l_empty == [] Out [161]: La vera In [162]: [] == [] Out [162]: Vero Non credo che è la ragione – volcano

0

È possibile definire una funzione per fare l'assegnazione per voi:

def assign(name, value): 
    import inspect 
    frame = inspect.currentframe() 
    try: 
     locals_ = frame.f_back.f_locals 
    finally: 
     del frame 
    locals_[name] = value 
    return value 

if assign('test', 0): 
    print("first", test) 
elif assign('xyz', 123): 
    print("second", xyz) 
Problemi correlati