Возвращаемые значения процедуры Python

В Python можно создать процедуру, которая не имеет явного возврата. то есть:.

def test(val):
    if 0 == val:
        return 8

Кроме того, можно присвоить результаты этой функции переменной:

>>> a = test(7)
>>> print `a`
'None'

Почему это так? Какая языковая логика стоит за этим непонятным дизайнерским решением? Почему это просто не вызывает ошибку компилятора?

EDIT: Да, я понимаю, что он работает именно так. Благодарю. Мой вопрос: ПОЧЕМУ? Кажется, что такой верный способ пожара ввести тонкие ошибки в ваш код. И, как было сказано ниже, e-satis, похоже, идет против очень мудрой пифонической пословицы, что "явный лучше, чем неявный".

Итак, что с этим? Является ли это просто надзором за дизайном или упрощающим предположением или преднамеренным, рассмотренным решением?

EDIT: согласны ли все с тем, что выражение этого намерения намного лучше:

def test(val):
    if 0 == val:
        return 8
    else:
        return None

Если да, то почему Python предпочитает, чтобы прежний стиль поднимал исключение времени компиляции?

РЕДАКТИРОВАТЬ: S.Lott явно указывает точку (и другие тоже делают это, как мне кажется, яснее всего ясно), что это поведение является результатом того, что Python является динамическим языком и поэтому не может проверяться при компиляции времени, времени работы системы.

Поскольку нет разграничения между процедурами (те функции, которые не возвращают значения) и функциями (теми, которые делают), что во время компиляции нечего принуждать. Это означает, что когда мы приходим к поведению во время выполнения, у нас либо есть катастрофический сбой в некоторых случаях (мы бросаем исключение), либо мы молчаем, полагая, что программист знал, что они делают, и понял поведение по умолчанию.

Питонический путь состоит в том, чтобы сделать последнее, способ стиля C - сделать первый.
Это, по-видимому, имеет смысл в качестве веской причины сделать это таким образом.

Ясное обоснование S.Lott похоронено в комментариях к принятому ответу, поэтому я подумал, что лучше всего обобщить здесь.

Я немного успокоюсь, чтобы принять ответ, чтобы узнать, дает ли S.Lott официальный ответ. В противном случае я дам очки SilentGhost.

Ответы

Ответ 1

Хотя каждая функция может не иметь явного возврата, она будет иметь неявный, то есть None, который, кстати, является обычным объектом Python. Кроме того, функции часто return None явно.

Я предполагаю, что возвращение None неявно является просто упрощенной оптимизацией.

P.S. Интересно, что вы предлагаете компиляции в следующем случае:

def t():
    if True:
        return 'ham'
Оператор

P.P.S. return указывает, что нужно вернуть , будь то None, 42 или 'spam'. Однако некоторые функции ничего не возвращают, например, list.sort или __init__, поэтому в конце каждого __init__ для накладных расходов потребуется инструкция return None.

Ответ 2

Python никогда не проверяет человеческое поведение. Философия языка предполагает, что программисты взрослые взрослые и знают, что они делают.

Так как:

  • Python - это язык с автодокументами, поэтому вы будете знать, что возвращает функцию;
  • Python использует утиную печать, поэтому получение None по умолчанию может значительно облегчить вызов динамической функции.

Возврат None делает больше чувств, чем вызывает ошибку.

E.G:

function_stack = [func1, func2, func3]

for f in function_stack :
    a = f()
    if a is not None :
        # do something

Независимо от того, f является f(), является функцией или процедурой. В Python такой вещи нет. Вы можете применить всю функцию и обработать вывод, если он есть.

Ответ 3

Хех. Подойдя к этому с точки зрения Java, ваш вопрос очевиден. Он должен выдать ошибку.

Но если вы пришли к нему с точки зрения Perl, это не очевидно. Вы устанавливаете переменную без значения, большое дело.

Это все о наборе текста. Как и Java, Python строго типизирован, но, в отличие от Java, он также динамически. Большинство динамически типизированных языков допускают такие махинации.

Ответ 4

Это красиво...

Он возвращает None в случае, когда val != 0, что для меня имеет смысл.

Python 2.6.1 (r261:67515, Jun 18 2009, 17:24:16)
[GCC 3.3.3 (SuSE Linux)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> def test(val):
...     if 0 == val:
...         return 8
...
>>> a = test(8)
>>> print a
None
>>> print test(0)
8
>>>

Есть ли у вас аргументы, почему вы считаете, что поведение неверно?

Вы можете использовать С++, если вам нужна сильная проверка типа времени компиляции, но для python она кажется чрезвычайно гибкой, и я предполагаю, что вы хотите, когда вы выбрали python для своей задачи.

Ответ 5

Какой компилятор? Компилятор байт-кода проверяет ваш код на синтаксис при импорте, но синтаксис не включает "проверить все пути для возврата". Поэтому, когда test() вызывается во время выполнения, а значение x не равно 0, и мы просто выпадали из функции, что нам делать? return 0? Почему не -1, или "", или -infinity? Поэтому хорошее нейтральное значение всегда должно возвращаться при отсутствии явного оператора return - и это значение равно None. Это стандартная функция языка - добро пожаловать на Python!

Ответ 6

Это из-за динамического ввода .

Вам не нужно проводить различие между, скажем, процедурой и функцией турбо-паскаля. Они все функции, они возвращают None по умолчанию, что логически корректно. Если вы ничего не говорите, он ничего не возвращает, None.

Надеюсь, теперь будет больше смысла -