2010-04-08 11 views
47

¿Es posible tener una asignación en una condición?¿Podemos tener una asignación en una condición?

Por ej.

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

-1: Trivial para responder a sí mismo. Duplicado: http://stackoverflow.com/questions/1663995/python-variable-assignment-and-if-statement –

+1

@ S.Lott No es tan trivial saber por qué, si no fuera por algunas de las respuestas que describen eso aquí. –

Respuesta

66

¿Por qué no probarlo?

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

Así que, no.

+17

esto está intencionalmente prohibido ya que Guido, el benévolo dictador pitón, los considera innecesarios y más confusos que útiles. Es la misma razón por la que no hay operadores de incremento o preincremento (++). –

+4

permitió la adición de * asignación aumentada * en 2.0 porque 'x = x + 1' requiere tiempo de búsqueda adicional, mientras que' x + = 1' fue algo más rápido, pero estoy seguro de que ni siquiera le gustó hacer * ese * mucho :-) – wescpy

4

No. La asignación en Python es una declaración, no una expresión.

+0

Y Guido no lo haría de otra manera. –

+0

@MarkRansom Todos saludan a Guido. * Derecha * .. suspiro. – javadba

+0

@javadba el tipo ha estado en lo correcto mucho más a menudo de lo que se ha equivocado. Aprecio que tener una sola persona a cargo de la visión tenga como resultado una estrategia mucho más coherente que el diseño por comité; Puedo comparar y contrastar con C++, que es mi principal pan y mantequilla. –

33

No, la BDFL no le gustó esa característica.

Desde donde estoy sentado, Guido van Rossum, "Dictador benevolente para la vida", ha luchado duro para mantener a Python tan simple como puede. Podemos objetar algunas de las decisiones que ha tomado. Hubiera preferido dijo "No" con más frecuencia. Pero el hecho de que no haya habido un comité que diseñe Python, sino un "consejo asesor" confiable, basado en gran medida en el mérito, filtrando a través de una sensibilidad del diseñador, ha producido un infierno de buen lenguaje, en mi humilde opinión

+3

¿Simple? Esta característica podría simplificar bastante parte de mi código porque podría haberlo hecho más compacto y, por lo tanto, más legible. Ahora necesito dos líneas donde solía necesitar una. Nunca entendí por qué Python rechazó las características que tienen otros lenguajes de programación durante muchos años (y con frecuencia por una muy buena razón). Especialmente esta característica de la que estamos hablando aquí es muy, muy útil. En –

11

No directamente, por this old recipe of mine - pero como la receta dice que es fácil construir el equivalente semántico, por ejemplo, si necesita transcribir directamente de un algoritmo de referencia codificado en C (antes de refactorizar a más idiomático Python, de cour se ;-) Es decir:

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 

Por cierto, una forma Pythonic muy idiomático para su caso específico, si usted sabe exactamente qué valor falsish somefunc puede regresar cuando no devuelve ningún valor falsish (por ejemplo 0), es

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

por lo que en este caso específico la refactorización sería bastante fácil ;-).

Si la devolución puede ser cualquier tipo de valor falseado (0, None, '', ...), Una posibilidad es:

import itertools 

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

pero es posible que prefiera un generador personalizado simple:

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

Una de las razones por las asignaciones son ilegales en condiciones es que es más fácil cometer un error y asignar Verdadero o Falso:

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 

En Python 3 verdadero y falso son palabras clave, por lo que no hay riesgo más.

+1

[161]: l_empty == [] de salida [161]: La verdadera En [162]: [] == [] de salida [162]: La verdadera No creo que esa es la razón – volcano

0

Se puede definir una función para hacer la asignación para usted:

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) 
Cuestiones relacionadas