Синтаксическая ошибка при передаче распакованного аргумента для печати в Python

#python #python-2.7 #argument-unpacking

#python #python-2.7 #аргумент-распаковка

Вопрос:

Вместо простой печати debug / log как это:

 print "error ", error_number
  

Я хотел бы использовать функцию журнала, которую я могу развернуть при необходимости, выглядящую примерно так:

 def log(condition, *message):
    if(<do something here...>):
        print(*message)
        <perhaps do something more...>
  

и назовите это так:

 log(condition, "error ", error_number)
  

Но я получаю следующую синтаксическую ошибку:

 print *message
      ^ SyntaxError: invalid syntax
  

Это ограничение функции печати или есть какой-то способ заставить ее работать? Если нет, есть ли эквивалент print, который я мог бы использовать?

Кстати, я использую Python 2.7…

Комментарии:

1. Я добавил способ изменить ваш скрипт без использования __future__ модуля; смотрите мой ответ.

Ответ №1:

print не является функцией в Python 2.x. В первом фрагменте вы печатаете кортеж, а последний имеет недопустимый синтаксис. Если вы хотите использовать функцию печати, вам нужно включить ее через from __future__ import print_function .

Ответ №2:

Если вы не хотите использовать __future__ , вы можете определить функцию ведения журнала следующим образом:

 def log(condition, *message):
    if(<do something here...>):
        print ' '.join(str(a) for a in message)
        <perhaps do something more...>
  

Ответ №3:

Вы должны использовать print message напрямую, этого достаточно (он напечатает кортеж дополнительных аргументов).


Небольшое дополнение к предыдущим ответам: в Python 2.x print является не функцией, а оператором, но print(arg1, arg2) допустимо … как использование print оператора в кортеже (arg1, arg2) .

Это немного отличается от print arg1, arg2 того, что можно видеть:

 >>> print 'aaa', 'bbb'
aaa bbb
>>> print('aaa', 'bbb')
('aaa', 'bbb')
  

Теперь, в дополнение к ответу themel:

случай 1: не используется * для расширения кортежа аргументов

 >>> def p(*args):
...     a(args)  # <== args is a tuple
>>> def a(*args):
...     print args  # <== args is a tuple (but nothing else can be used)
>>> p('bb')
(('bb',),)
  

Результатом является кортеж из кортежа.

Случай 2: расширение аргументов в p :

 >>> def p(*args):
...      a(*args)  # <== now arguments are expanding
...
>>> p('bb')
('bb',)
  

Результатом является кортеж аргументов, переданных p .

Так *args правильно использовать, но это не разрешено в инструкции.

Комментарии:

1. Хорошая информация о том, что основная проблема здесь заключается в том, что print — это оператор (фанковый), и что операторы не поддерживают распакованные аргументы (даже если они являются фанковыми операторами, принимающими переменные аргументы)

2. использование print message напрямую выводит кортеж как «(‘error’, 22)» вместо «error 22». Пробовал это перед публикацией, но это не то, что я хотел.

3. Затем вопрос: ваш код print("error ", error_number) делал то, что вы ожидали? Я бы сказал, нет, поскольку print ('error ', 3) печатает ('error ', 3) , а не error 3 напрямую. Итак, это правильно, вам нужна была новая версия print.

4. К сожалению, изначально в моем коде было много print "error", 3 подобных строк (печатающих то, что я ожидал). Когда я пытался заставить метод log работать, я перепробовал много разных синтаксисов, и в вопросе оказался тот, который содержит скобки. Вопрос обновлен.

Ответ №4:

Вы просто используете *args для объявления кортежа аргументов, а не для доступа к нему. Смотрите пример в документах:

 def write_multiple_items(file, separator, *args):
    file.write(separator.join(args))
  

Тот факт, что вы получаете SyntaxError , должен подсказать вам, что в любом случае это не имеет никакого отношения к print .

Комментарии:

1. @themel Нет, это неправильно, смотрите Мой ответ: если вы не расширяете, вы получаете кортеж; если вы расширяете, вы получаете несколько аргументов. Это разрешено где угодно. В любом случае, ваш пример правильный, поскольку в этом случае вам нужно использовать кортеж.