2009-11-02 20 views
38

Vengo de un fondo de PHP y me gustaría saber si hay una manera de hacerlo en Python.¿Cómo evitar escribir request.GET.get() dos veces para imprimirlo?

En PHP se puede matar 2 pájaros de un tiro como esto:

En lugar de:

if(getData()){ 
    $data = getData(); 
    echo $data; 
} 

que pueda hacer esto:

if($data = getData()){ 
    echo $data; 
} 

comprobar para ver si getData() existe Y si lo hace, se lo asigna a una variable en una declaración.

¿Quería saber si hay una manera de hacer esto en Python? Así que en lugar de hacer esto:

if request.GET.get('q'): 
    q = request.GET.get('q') 
    print q 

evitar escribir request.GET.get('q') dos veces.

+0

¿Tiene un tutorial de Python marcado? ¿Cúal? –

+1

Solo la oficial: http://docs.python.org/tutorial/ – givp

+2

Afortunadamente, Python no tiene esta característica errónea C, y en general, en la mayoría de los lenguajes que la heredaron de C/C++, su uso está mal visto por razones de legibilidad y legibilidad. –

Respuesta

25

Probablemente no es exactamente lo que estaba pensando, pero ...

q = request.GET.get('q') 
if q: 
    print q 

esto?

+0

sí, eso es correcto. el patrón es usar una variable si y solo si existe (lo que significa que da un valor válido, es decir, cualquier cosa menos * Falso *). –

+0

Gracias, parece que esta es la mejor manera de hacerlo. Como dice @Adam, no es posible hacer esto en Python. Gracias. – givp

+7

La limitación de esta solución es si desea usarla en una serie de if-elif-elif-elif, etc. Por ejemplo, vea esta otra pregunta de SO: http://stackoverflow.com/questions/122277/how-do -you-translate-this-regular-expression-idiom-from-perl-into-python –

24

Consulte mi receta de 8 años here para esta tarea.

# In Python, you can't code "if x=foo():" -- assignment is a statement, thus 
# you can't fit it into an expression, as needed for conditions of if and 
# while statements, &c. No problem, if you just structure your code around 
# this. But sometimes you're transliterating C, or Perl, or ..., and you'd 
# like your transliteration to be structurally close to the original. 
# 
# No problem, again! One tiny, simple utility class makes it easy...: 

class DataHolder: 
    def __init__(self, value=None): self.value = value 
    def set(self, value): self.value = value; return value 
    def get(self): return self.value 
# optional but handy, if you use this a lot, either or both of: 
setattr(__builtins__,'DataHolder',DataHolder) 
setattr(__builtins__,'data',DataHolder()) 

# and now, assign-and-set to your heart's content: rather than Pythonic 
while 1: 
    line = file.readline() 
    if not line: break 
    process(line) 
# or better in modern Python, but quite far from C-like idioms: 
for line in file.xreadlines(): 
    process(line) 
# you CAN have your C-like code-structure intact in transliteration: 
while data.set(file.readline()): 
    process(data.get()) 
+29

¡Tienes un niño de 8 años bastante inteligente! ;) – unutbu

+2

@unutbu, heh - ese sería mi gato (más viejo) ya que mis hijos son un poco mayores ... mi hija menor acaba de comenzar su doctorado en ingeniería de telecomunicaciones (sistemas de radio avanzados, principalmente) ... ;-) –

0

Bueno, esto sería una forma

q = request.GET.get('q') 
if q: 
    print q 

Una breve (pero no superior, debido a la llamada a imprimir de la nada) forma sería

print request.GET.get('q') or '', 
2
q = request.GET.get('q') 
if q: 
    print q 
else: 
    # q is None 
    ... 

No hay forma de hacer asignaciones y condicionales de una vez ...

+0

Explícito es mejor que implícito. La legibilidad cuenta Los casos especiales no son lo suficientemente especiales como para romper las reglas. Está ahorrando tanto espacio vertical en su código al no escribir todas esas líneas con nada más que un corsé derecho, entonces ¿por qué no ir por claridad en Python? Personalmente, corté mis dientes en C y he estado escribiendo el código de Python durante 12 años, y nunca me di cuenta de que esta característica faltaba. Simplemente no necesitas hacer esto. –

+0

@Michael: estoy de acuerdo en casi todos los casos. Solo me falta el caso de uso específico de probar expresiones regulares múltiples, como se describe en esta otra pregunta SO: http://stackoverflow.com/questions/122277/how-do-you-translate-this-regular-expression- idiom-from-perl-into-python –

2

Si get() lanza una excepción cuando no está allí, usted podría hacer

try: 
    q = request.GET.get('q') 
    print q 
except : 
    pass 
9

Una variación en Alex's answer:

class DataHolder: 
    def __init__(self, value=None, attr_name='value'): 
     self._attr_name = attr_name 
     self.set(value) 
    def __call__(self, value): 
     return self.set(value) 
    def set(self, value): 
     setattr(self, self._attr_name, value) 
     return value 
    def get(self): 
     return getattr(self, self._attr_name) 
save_data = DataHolder() 

Uso:

if save_data(get_input()): 
    print save_data.value 

o si lo prefiere una interfaz alternativa:

if save_data.set(get_input()): 
    print save_data.get() 

Me ha resultado útil para poner a prueba una serie de expresiones regulares en un if-elif-elif-elif etc construir, como en this SO question:

import re 

input = u'test bar 123' 
save_match = DataHolder(attr_name='match') 
if save_match(re.search('foo (\d+)', input)): 
    print "Foo" 
    print save_match.match.group(1) 
elif save_match(re.search('bar (\d+)', input)): 
    print "Bar" 
    print save_match.match.group(1) 
elif save_match(re.search('baz (\d+)', input)): 
    print "Baz" 
    print save_match.match.group(1) 
+0

Me gusta su adición de '__call __()' a DataHolder, pero no entiendo por qué es útil especificar 'attr_name'. Si DataHolder fuera un singleton o si una instancia de él pudiera contener múltiples valores, cada uno en diferentes atributos, lo entendería, pero no parece tener un fuerte propósito aquí. –

+1

@LS: Sí, podría haberlo arreglado para que sea 'value' o' x'.Pero [buenos nombres de variables] (http://c2.com/cgi/wiki?GoodVariableNames) mejoran la legibilidad. Esa es la esencia de eso. –

0
config_hash = {} 
tmp_dir = ([config_hash[x] for x in ["tmp_dir"] if config_hash.has_key(x)] or ["tmp"])[0] 
print tmp_dir 
config_hash["tmp_dir"] = "cat" 
tmp_dir = ([config_hash[x] for x in ["tmp_dir"] if config_hash.has_key(x)] or ["tmp"])[0] 
print tmp_dir 
0

una posible manera de hacerlo, sin necesidad de establecer la variable antes, podría ser como:

if (lambda x: globals().update({'q':x}) or True if x else False)(request.GET.get('q')): 
    print q 

..es solo por diversión, este método no debe usarse, porque es feo, difícil de entender a primera vista, y crea/sobrescribe una variable global (solo si se cumple la condición)

0

Simplemente intente:

print(request.GET.get('q', '')) 

que básicamente imprime nada si el primer argumento no está presente (ver dict.get).


solución alternativa sería utilizar una expresión condicional en Python:

<expression1> if <condition> else <expression2> 

pero podrá llegar a repetir dos veces la variable, por ejemplo:

print(request.GET.get('q') if request.GET.get('q') else '') 

Para asignaciones variables en bucles, check in here.

Cuestiones relacionadas