135 votes

Peut-on avoir une affectation dans une condition ?

Est-il possible d'avoir une affectation dans une condition ?

Par exemple.

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

5voto

Non. L'assignation en Python est une déclaration, pas une expression.

4voto

Jean-François Fabre Points 94672

Merci à Nouvelle fonctionnalité de Python 3.8 il sera possible de faire une telle chose à partir de cette version, bien qu'elle n'utilise pas = mais l'opérateur d'affectation de type Ada := . Exemple tiré de la documentation :

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

2voto

Willem Hengeveld Points 1387

Vous pouvez définir une fonction qui se chargera de l'affectation à votre place :

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)

1voto

user2979916 Points 1

L'une des raisons pour lesquelles les affectations sont illégales dans les conditions est qu'il est plus facile de faire une erreur et d'affecter Vrai ou Faux :

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

Dans Python 3, Vrai et Faux sont des mots-clés, donc plus de risque.

1voto

BPL Points 5420

L'opérateur d'affectation - également connu de manière informelle sous le nom d'opérateur morse - a été créé le 28 février 2018 dans le cadre de l'initiative de la Commission européenne. PEP572 .

Dans un souci d'exhaustivité, je vais publier les parties concernées afin que vous puissiez comparer les différences entre 3.7 et 3.8 :

3.7
---
if_stmt: 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT
test: or_test ['if' or_test 'else' test] | lambdef
test_nocond: or_test | lambdef_nocond
lambdef: 'lambda' [varargslist] ':' test
lambdef_nocond: 'lambda' [varargslist] ':' test_nocond
or_test: and_test ('or' and_test)*
and_test: not_test ('and' not_test)*
not_test: 'not' not_test | comparison
comparison: expr (comp_op expr)*

3.8
---
if_stmt: 'if' namedexpr_test ':' suite ('elif' namedexpr_test ':' suite)* ['else' ':' suite]
namedexpr_test: test [':=' test]                         <---- WALRUS OPERATOR!!!
test: or_test ['if' or_test 'else' test] | lambdef
or_test: and_test ('or' and_test)*
and_test: not_test ('and' not_test)*
not_test: 'not' not_test | comparison
comparison: expr (comp_op expr)*

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X