2010-04-08 4 views
47

Возможно ли иметь назначение в состоянии?Можем ли мы иметь назначение в состоянии?

Для примера.

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

-1: Trivial ответить самостоятельно. Дубликат: http://stackoverflow.com/questions/1663995/python-variable-assignment-and-if-statement –

+1

@ S.Lott Не так уж и сложно узнать, почему, если бы не некоторые ответы, которые описывают это Вот. –

ответ

66

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

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

Итак, нет.

+17

это намеренно запрещено, поскольку Гвидо, доброжелательный диктатор питона, считает их ненужными и более запутанными, чем полезными. По той же причине нет операторов пост-инкремента или пред-инкремента (++). –

+4

он разрешил добавление * дополненного присваивания * в 2.0, потому что 'x = x + 1' требует дополнительного времени поиска, в то время как' x + = 1' был несколько быстрее, но я уверен, что он даже не любил делать *, что * много. :-) – wescpy

4

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

+0

И у Гвидо не было бы этого иначе. –

+0

@MarkRansom Все град Гвидо. * Вправо * .. вздох. – javadba

+0

@javadba парень был прав гораздо чаще, чем он был неправ. Я признателен, что наличие единого лица, ответственного за видение, приводит к гораздо более согласованной стратегии, чем дизайн комитета; Я могу сравнить и сравнить с C++, который является моим основным хлебом и маслом. –

15

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

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

также смотрите:

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

33

Nope, то BDFL не нравится эта функция.

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

+3

Простой? Эта функция может упростить некоторые из моих кодов, потому что это могло бы сделать ее более компактной и, следовательно, более читаемой. Теперь мне нужны две строки, в которых я был нужен. Я никогда не понимал, почему Python отвергает функции других языков программирования на протяжении многих лет (и часто по очень веской причине). Особенно эта особенность, о которой мы говорим, очень и очень полезна. –

+1

Меньше кода не всегда проще или удобочитаемы. Возьмем, например, рекурсивную функцию. Это эквивалент цикла, который часто читается. –

11

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

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 

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

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

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

Если возвращение может быть любое вид величины 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 
1

Одна из причин назначения являются незаконными в условиях, что это легче сделать ошибку и назначить Правда или 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 Истина и ложь - это ключевые слова, поэтому больше не рискуйте.

+1

В [161]: l_empty == [] Out [161]: Правда В работе [162]: [] == [] Out [162]: Правда я не думаю, что причина – volcano

0

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

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) 
Смежные вопросы