Почему скобка необязательна при определении класса, но обязательна при определении функции?

В Python для определения функции с пустым списком параметров требуется набор пустых скобок. Однако определение a class со стандартным суперклассом не требует набора пустых круглых скобок; скорее, они являются необязательными и кажутся необычными. Почему это так?

См. также: Синтаксис определения класса Python.

Ответ 1

Я думаю, что ответ на ваш вопрос - просто синтаксис. Это как раз то, как Python настроен, но я понимаю, как это получилось:

Я бы подумал, что функции вышли из математики, например:

f(x) = x

Итак, когда создавались языки компьютерного программирования, по-видимому, была некоторая логическая непрерывность от аналоговой математики до языков программирования.

С другой стороны, классы - это больше конструкций Информатики и многократного управления памятью, поэтому они не были созданы таким образом, но поскольку у них есть функциональное качество, им были даны аналогичные обозначения.

Для Python я буду использовать термин method для function, поскольку это обычный язык...

Я понимаю ваш аргумент, что как a class, так и method должно быть разрешено определять с помощью короткого вырезания в случае отсутствия аргумента:

  • для class es, когда нет наследования
  • для method, когда нет аргументов

Одна из причин, о которой я могу думать, - это согласованность использования и определения. Рассмотрим несколько примеров:

определение:

def funcA():
    return 0

def funcB(arg):
    return arg

и вы хотите назвать этот funciton:

>>> funcA()
>>> functB("an argument")

и

>>> f1 = funcA
>>> f2 = funcB
>>> f1()
>>> f2("another argument")

передать ссылки и вызвать их.

Синтаксис paranthesis между объявлением method согласуется с вызовом methods.

Вам нужно поместить эти пустые скобки, иначе интерпретатор даст вам ссылку на method, а не на самом деле вызовет его.

Таким образом, одно из преимуществ заключается в том, что ваш код очень понятен.

определение:

class classA:
    pass

class classB(object):
    pass

использование:

# create an instance
my_instance_of_A = classA()
my_instance_of_B = classB()

# pass a reference
my_ref_to_A = classA
my_ref_to_B = classB

# call by reference
new_A = my_ref_to_A()
new_B = my_ref_to_B()

Здесь нет изменений в поведении относительно того, наследует ли /t 23 > или нет, его поведение при вызове диктуется тем, что его внутренний или унаследованный метод __init__ определяется как.

Я думаю, что текущая настройка требуемого пустого () делает код более понятным для неподготовленного глаза.

Если вы действительно действительно хотите делать то, что вы просите, есть обходной путь... вы всегда можете это сделать:

func = lambda: "im a function declared with no arguments, and I didn't use parenthesis =p"

который можно назвать:

>>> func
<function <lambda> at 0x6ffffef26e0>
>>> func()
"im a function declared with no arguments, and I didn't use parenthesis =p"

Но Священная книга питона говорит Нет