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.
Probablement pas exactement ce que vous pensiez, mais ...
q = request.GET.get('q')
if q:
print q
ce?
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())
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)
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 ...
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
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 '',
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]
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
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)
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 .