web-dev-qa-db-fra.com

Comment éviter d'écrire request.GET.get () deux fois afin de l'imprimer?

Je viens de PHP et je voudrais savoir s’il est possible de le faire en Python. 

Dans PHP vous pouvez tuer deux oiseaux avec une pierre comme celle-ci:

Au lieu de:

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

Je peux le faire:

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

Vous vérifiez si getData() existe ET si c'est le cas, vous l'affectez à une variable dans une instruction.

Je voulais savoir s'il y avait un moyen de faire cela en Python? Donc au lieu de faire ceci:

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

évitez d'écrire request.GET.get('q') deux fois.

40
givp

Probablement pas exactement ce que vous pensiez, mais ...

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

ce?

25
Amber

Voir ma recette de 8 ans ici pour cette tâche.

# 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())
25
Alex Martelli

Une variation sur La réponse d'Alex :

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()

Usage:

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

ou si vous préférez une interface alternative:

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

Cela me serait utile de tester une série d'expressions régulières dans une construction if-Elif-elif-Elif, etc., comme dans cette 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)
9
Craig McQueen
q = request.GET.get('q')
if q:
    print q
else:
    # q is None
    ...

Il n'y a aucun moyen de faire une cession et des conditions en une fois ...

2
Adam

Si get () lève une exception alors qu'elle n'est pas là, vous pourriez le faire 

try:
   q = request.GET.get('q')
   print q
except :
   pass
1
Rizwan Kassim

Eh bien, ce serait une façon

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

Une manière plus brève (mais pas supérieure, à cause de l’appel à imprimer) serait

print request.GET.get('q') or '',
0
Grumdrig

PEP 572 introduit les expressions Assignment. À partir de Python 3.8, vous pouvez écrire:

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

Voici d'autres exemples tirés de la syntaxe et de la sémantique du PEP:

# Handle a matched regex
if (match := pattern.search(data)) is not None:
    # Do something with match

# A loop that can't be trivially rewritten using 2-arg iter()
while chunk := file.read(8192):
   process(chunk)

# Reuse a value that's expensive to compute
[y := f(x), y**2, y**3]

# Share a subexpression between a comprehension filter clause and its output
filtered_data = [y for x in data if (y := f(x)) is not None]
0
timgeb
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
louis_xv

une façon possible de le faire, sans qu'il soit nécessaire de définir la variable avant, pourrait être la suivante:

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

.. c'est juste pour le plaisir - cette méthode ne doit pas être utilisée, car elle est laide, difficile à comprendre à première vue, et crée/écrase une variable globale (seulement si la condition est remplie)

0
mykhal

Essayez simplement:

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

qui n'imprime rien si le premier argument n'est pas présent (voir dict.get ).


Une solution alternative consisterait à utiliser une expression conditionnelle en Python:

<expression1> if <condition> else <expression2>

mais vous finirez par répéter la variable deux fois, par exemple:

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

Pour les affectations de variables dans les boucles, vérifiez dans ici .

0
kenorb