Почему это булевское выражение не разрешено как условие цикла while в Python? [Дубликат]

Чтобы использовать методы и член объекта, вам сначала нужно создать этот объект. Если вы его не создали (переменная, которая должна содержать объект, не инициализируется), но вы пытаетесь использовать его методы или переменные, вы получите эту ошибку.

Иногда вы можете просто забыть инициализировать .

Отредактировано: new не может вернуть значение null, но исключение огня при ошибке. Давно это было на некоторых языках, но не больше. Спасибо @John Saunders за указание на это.

50
задан Vishal 8 April 2010 в 23:45
поделиться

7 ответов

Почему бы не попробовать?

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

Итак, нет.

70
ответ дан Jason Hall 3 September 2018 в 14:10
поделиться
  • 1
    это намеренно запрещено, поскольку Гвидо, доброжелательный диктатор питона, считает их ненужными и более запутанными, чем полезными. По той же причине нет операторов пост-инкремента или пред-инкремента (++). – Matt Boehm 8 April 2010 в 23:53
  • 2
    он допустил добавление расширенного присваивания в 2.0, потому что x = x + 1 требует дополнительного времени поиска, а x += 1 был несколько быстрее, но я уверен, что ему даже не нравилось делать , что < / i> много. :-) – wescpy 9 April 2010 в 00:56
  • 3
    Он входит в Python 3.8 – Étienne 17 August 2018 в 13:16

Не прямо, за этот старый мой рецепт - но, как говорится в рецепте, легко построить семантический эквивалент, например. если вам нужно транслитерировать непосредственно из C-кодированного эталонного алгоритма (до рефакторинга на более -диоматический Python, конечно ;-). Т.е.:

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

BTW, очень идиоматическая питоническая форма для вашего конкретного случая, если вы точно знаете, какое значение falsish somefunc может вернуться, когда оно вернет значение фальшивости (например, 0),

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

, поэтому в этом конкретном случае рефакторинг будет довольно простым; -).

Если return может быть любым значением falsish (0, None, '', ...), одна из возможностей:

import itertools

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

, но вы можете предпочесть простой пользовательский генератор:

def getwhile(func, *a, **k):
    while True:
      x = func(*a, **k)
      if not x: break
      yield x

for a in getwhile(somefunc):
    # use a
13
ответ дан Alex Martelli 3 September 2018 в 14:10
поделиться
  • 1
    Я бы проголосовал за это дважды, если мог. Это отличное решение для тех времен, когда действительно необходимо что-то подобное. Я адаптировал ваше решение к классу Matcher регулярного выражения, который создается один раз, а затем .check () используется в выражении if и .result (), используемом внутри его тела, для получения соответствия, если таковой был. Благодаря! :) – Teekin 26 July 2018 в 15:23

Нет. Назначение в Python - это выражение, а не выражение.

4
ответ дан Ignacio Vazquez-Abrams 3 September 2018 в 14:10
поделиться
  • 1
    И у Гвидо не было бы другого пути. – Mark Ransom 8 April 2010 в 23:51
  • 2
    @MarkRansom Все приветствуют Гвидо. Правильно .. вздох. – javadba 11 December 2017 в 05:49
  • 3
    @javadba парень был прав гораздо чаще, чем он был неправ. Я признателен, что наличие единого лица, ответственного за видение, приводит к гораздо более согласованной стратегии, чем дизайн комитета; Я могу сравнить и сравнить с C ++, который является моим основным хлебом и маслом. – Mark Ransom 11 December 2017 в 05:58
  • 4
    Я чувствую, что и рубин, и scala (v на разных языках) получают это право значительно выше, чем python: но в любом случае здесь не место. – javadba 11 December 2017 в 07:11

http://docs.python.org/tutorial/datastructures.html

Обратите внимание, что в Python, в отличие от C, присваивание не может происходить внутри выражений. Программисты C могут ворчать об этом, но он избегает общего класса проблем, встречающихся в программах на C: typing = в выражении, когда == был предназначен.

также см .:

http://effbot.org/pyfaq/why-can-ti-use-an-assignment-in-an-expression.htm

16
ответ дан John La Rooy 3 September 2018 в 14:10
поделиться

Нет, BDFL не понравилась эта функция.

С того места, где я сижу, Guido van Rossum, «Benevolent Dictator For Life», изо всех сил старался держать Python настолько простым, насколько это возможно. Мы можем спорить с некоторыми из решений, которые он принял, - я бы предпочел, чтобы он говорил «Нет» чаще, но тот факт, что не было комитета, проектирующего Python, а вместо этого доверенный «консультативный совет», основанный в основном по заслугам, фильтруя через одно чувства дизайнера, произвел один адский приятный язык, ИМХО.

35
ответ дан Kevin Little 3 September 2018 в 14:10
поделиться
  • 1
    Просто? Эта функция может упростить некоторые из моих кодов, потому что это могло бы сделать ее более компактной и, следовательно, более читаемой. Теперь мне нужны две строки, в которых я был нужен. Я никогда не понимал, почему Python отвергает функции других языков программирования на протяжении многих лет (и часто по очень веской причине). Особенно эта особенность, о которой мы говорим, очень и очень полезна. – Regis May 10 September 2017 в 08:09
  • 2
    Меньше кода не всегда проще или удобочитаемым. Возьмем, например, рекурсивную функцию. Это эквивалент цикла, который часто читается. – F.M.F. 9 April 2018 в 08:50
  • 3
    Мне не нравится, как версия C, но я действительно скучаю, имея что-то вроде ржавчины if let, когда у меня есть цепочка if elif, но вам нужно хранить и использовать значение условия в каждом случае. – Thayne 10 July 2018 в 04:57

Одна из причин, по которой присвоения являются незаконными в условиях, состоит в том, что легче совершить ошибку и назначить True или False:

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

В Python 3 True и False являются ключевыми словами, поэтому больше никакого риска .

1
ответ дан user2979916 3 September 2018 в 14:10
поделиться
  • 1
    В [161]: l_empty == [] Out [161]: True In [162]: [] == [] Out [162]: Правда, я не думаю, что это причина – volcano 2 January 2014 в 15:23

Вы можете определить функцию для назначения для вас:

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)
1
ответ дан Willem Hengeveld 3 September 2018 в 14:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: