В Python, в чем разница между передачей и возвратом

#python

#python

Вопрос:

Я видел некоторый код в Pinax и других приложениях django, в котором вместо pass используется пустой оператор return. В чем разница и повлияет ли это, например, на приведенный ниже код django, который я запускаю? Код представляет собой метод signal, который автоматически сохраняет хэштеги в объекты тегов taggit для объекта tweet.

Я видел здесь вопрос о том, влияет ли наличие или отсутствие оператора return в PHP на интерпретируемый байт-код, но я не уверен, имеет ли это отношение к Python.

 import re
TAG_REGEX = re.compile(r'#(?P<tag>w )')

def get_tagged(sender, instance, **kwargs):
    """
    Automatically add tags to a tweet object.
    """
    if not instance:
        return # will pass be better or worse here?
    post = instance
    tags_list = [smart_unicode(t).lower() for t in list(set(TAG_REGEX.findall(post.content)))]
    if tags_list:
        post.tags.add(*tags_list)
        post.save()
    else:
        return # will a pass be better or worse here?
post_save.connect(get_tagged, sender=Tweet)
  

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

1. например, вы не можете определить функцию/ … тупик без чего-либо в нем. Pass — это noop / nullop

Ответ №1:

 if not instance:
    return # will pass be better or worse here?
  

Хуже. Это меняет логику. pass на самом деле означает: ничего не делать. Если бы вы заменили return на pass here , поток управления продолжился бы, изменив семантику кода.

Целью pass является создание пустых блоков, что невозможно в противном случае с помощью схемы отступов Python. Например, пустая функция в C выглядит так:

 void foo()
{
}
  

В Python это было бы синтаксической ошибкой:

 def foo():
  

Вот где pass пригодится:

 def foo():
    pass
  

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

1. не будет ли def foo(): return делать то же самое, def foo(): pass что и?

2. @JayWalker В этом конкретном случае; да, они сделали бы то же самое.

Ответ №2:

Это иллюстрирует некоторые более ранние ответы.

 def p():
  "Executes both blocks."
  if True:
    print(1)
    pass
  if True:
    print(2)
    pass

def r():
  "Executes only the first block."
  if True:
    print(1)
    return
  if True:
    print(2)
    return
  

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

1. Принятый ответ лучше всего отражает «дух» различия, но этот ответ отлично объясняет функциональную разницу. 🙂

Ответ №3:

Return завершает текущую функцию или метод. Pass — это нулевая операция, которая позволяет продолжить выполнение в следующем операторе.

Ответ №4:

 if not instance:
    return # will pass be better or worse here?
  

a pass продолжит выполнение метода. A return завершит выполнение метода. Что касается следующих строк, которые вы хотите поместить return здесь.

 else:
    return # will a pass be better or worse here?
  

здесь это не имело бы значения. Даже удаление целых двух строк ничего не изменит.

Но в любом случае, представьте, что вы бы доработали метод дальше. Лучше выбрать правильный поток с самого начала.

Ответ №5:

Это скорее комментарий, чем ответ, но он не подходит в качестве комментария.

 if not instance:
    return # will pass be better or worse here?
  

Как объяснено в принятом ответе, pass было бы неверно.

 else:
    return # will a pass be better or worse here?
  

Здесь, поскольку мы находимся в конце функции, pass мы сделали бы то же самое: ничего. Еще лучше было бы полностью отказаться от else предложения, поскольку делать нечего. (Это правда, что «явное лучше, чем неявное» в Zen, но это редко относится к явному бездействию — ясно, что происходит в else случае, любому, кто на самом деле даже задается этим вопросом в первую очередь.)

(Также неясно, почему вы переименовываете instance в post внутри функции — вы могли бы просто изменить имя параметра? — или для чего sender должен быть аргумент. О, и вам на самом деле не нужно преобразовывать a set в a list , чтобы перебирать его в понимании списка. 🙂 )

Ответ №6:

 if not instance:
    return # will pass be better or worse here?
  

Это будет хуже, потому что в этом случае он выполнит следующую строку кодов в вашей определенной функции, даже если ее нет instance .

pass имеет свою собственную сущность, она используется для определения пустых блоков, ее не следует рассматривать как альтернативу return оператору.

Ответ №7:

Смотрите Документы python о передаче и возврате. В вашем текущем коде на самом деле нет разницы (на самом деле, я бы else полностью оставил away).

Разница в основном в семантике: pass может использоваться там, где оператор синтаксически требуется, но (пока) не нужен. С другой стороны, return выполняет своего рода контракт для функции, предоставляя явный результат.

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

1. Я прочитал документы перед публикацией, но на самом деле не понял этого: «В функции генератора оператору return не разрешается включать expression_list . В этом контексте пустой возврат указывает на то, что генератор завершен, и вызовет вызов StopIteration.» Теперь ясно, что это просто означает «выйти из потока» 😉 Спасибо!