Как был выбран синтаксис для статических методов в Python?
Я работаю с Python некоторое время, и я нахожу синтаксис для объявления методов как статических, чтобы быть своеобразным.
Будет объявлен обычный метод:
def mymethod(self, params)
...
return
Объявлен статический метод:
def mystaticethod(params)
...
return
mystaticmethod = staticmethod(mystaticmethod)
Если вы не добавляете статическую линию метода, компилятор жалуется на отсутствие себя.
Это очень сложный способ сделать что-то очень простое, что на других языках просто используйте ключевое слово и грамматику декларации. Может ли кто-нибудь рассказать мне об эволюции этого синтаксиса? Это просто потому, что классы добавлены в существующий язык?
Так как я могу перемещать линию staticmethod позже в классе, это также предполагает, что
синтаксический анализатор работает с избытком при бухгалтерии.
Обратите внимание, что я знаю о синтаксисе декоратора, который был добавлен позже, мне интересно узнать, как появился оригинальный синтаксис с точки зрения дизайна языка. Единственное, о чем я могу думать, это то, что приложение staticmethod вызывает операцию, которая преобразует объект функции в статический метод.
Ответы
Ответ 1
Статические методы были добавлены в Python долго после того, как были классы (классы были добавлены очень рано, возможно, даже до 1.0, статические методы не отображались до примерно 2.0). Они были реализованы как модификация обычных методов; вы создаете объект статического метода из функции для получения статического метода, тогда как компилятор по умолчанию генерирует методы экземпляра.
Как и во многих вещах в Python, статические методы были введены, а затем уточнены по мере того, как люди использовали их и нуждались в улучшенном синтаксисе. Первоначальный раунд был способом введения семантики без добавления нового синтаксиса к языку (и Python вполне устойчив к изменениям синтаксиса). Я не Гвидо, поэтому я не совсем уверен, что происходит в его голове, и это несколько спекулятивно, но Python имеет тенденцию двигаться медленно, постепенно развиваться и улучшать вещи, поскольку они приобретают больше опыта с ними (в частности, им не нравится добавлять что-то, пока они не выяснят правильный способ сделать это. Возможно, это было почему не было специального синтаксиса для статических методов с самого начала).
Как указано в mjv, теперь есть более простой способ: через некоторый синтаксический сахар, добавленный в 2.2 или 2.3 под названием "декораторы":
@staticmethod
def mystaticmethod(params)
...
return
Синтаксис @staticmethod
- это сахар для размещения mystaticmethod = staticmethod(mystaticmethod)
после определения метода.
Ответ 2
voyager и adurdin делают хорошую работу между ними, объясняя, что произошло: с введением классов и дескрипторов нового стиля в Python 2.2 появились новые и глубокие семантические возможности - и наиболее очевидные полезные примеры (статические методы, методы класса, свойства) поддерживались встроенными типами дескрипторов без какого-либо нового синтаксиса (синтаксис @foo
для декораторов был добавлен пару релизов позже, как только новые дескрипторы вполне доказали свою реальную полезность). Я не очень квалифицирован, чтобы направить Гвидо (где Тим Питерс, когда он вам нужен!), Но в то время я уже был комбатантом Питона и участвовал в этих событиях, и я могу подтвердить, что действительно то, что произошло.
наблюдение вояджера над этим напоминанием ему о C является правильным на цель: я давно утверждал, что Python захватывает больше "Духа C", чем любой из языков, которые имитировали синтаксис C (скобки, скобки после if/while и т.д.). "Дух C" фактически описан в (ненормативной) части Обоснования стандарта ISO C и состоит из пяти принципов (ни один из которых не требует брекетов!), Из которых я утверждаю, что Python соответствует 4.5 (есть несколько видеороликов на сеть презентаций на тему "Python for Programmers", где я рассказываю об этом, если вам интересно).
В частности, Дух C "обеспечивает только один способ выполнения операции" соответствует Zen Python ". Должен быть один - и желательно только один - простой способ сделать это" - и C и Python, Я считаю, являются единственными двумя широко распространенными языками для явного принятия такого конструктивного идеала единообразия и отсутствия избыточности (он идеален и не может быть разумно достигнут на 100% - например, если a и b являются целыми числами, a + b и b + a ЛУЧШЕ было два одинаково очевидных способа получить свою сумму! -) - но это цель для цели! -).
Ответ 3
Статические методы в python датируются введением в Python 2.2 так называемых "классов нового стиля". До этого методы в классах были просто обычными функциями, хранящимися как атрибуты класса:
class OldStyleClass:
def method(self):
print "'self' is just the first argument of this function"
instance = OldStyleClass()
OldStyleClass.method(instance) # Just an ordinary function call
print repr(OldStyleClass.method) # "unbound method..."
Вызов методов для экземпляров был специально обработан для автоматической привязки экземпляра к первому аргументу функции:
instance.method() # 'instance' is automatically passed in as the first parameter
print repr(instance.method) # "bound method..."
В Python 2.2 большая часть системы классов была переосмыслена и переработана как классы класса "новый стиль", которые наследуют от object
. Одной из особенностей классов нового стиля было "дескрипторы", по существу, объект класса, который отвечает за описание, получение и установку атрибутов класса. Дескриптор имеет метод __get__
, который получает класс и экземпляр и должен возвращать запрошенный атрибут класса или экземпляра.
Дескрипторы позволили использовать один API для реализации сложного поведения для атрибутов класса, таких как свойства, методы класса и статические методы. Например, дескриптор staticmethod
может быть реализован следующим образом:
class staticmethod(object):
"""Create a static method from a function."""
def __init__(self, func):
self.func = func
def __get__(self, instance, cls=None):
return self.func
Сравните это с гипотетическим дескриптором pure-python для обычного метода, который по умолчанию используется для всех простых функций в атрибутах классов (это не совсем то, что происходит с поиском метода из экземпляра, но оно обрабатывает автоматический аргумент "self" ):
class method(object):
"""Create a method from a function--it will get the instance
passed in as its first argument."""
def __init__(self, func):
self.func = func
def __get__(self, instance, cls=None):
# Create a wrapper function that passes the instance as first argument
# to the original function
def boundmethod(*args, **kwargs):
return self.func(self, *args, **kwargs)
return boundmethod
Итак, когда вы пишете method = staticmethod(method)
, вы на самом деле создаете новый дескриптор, чья работа заключается в том, чтобы вернуть исходную функцию без изменений и сохранить этот дескриптор в атрибуте "метод" класса.
Если вам кажется, что нужно много работать, чтобы получить исходную функцию обратно, вы правы. Но так как обычные вызовы методов являются стандартным случаем, статические методы и методы класса должны быть реализованы отдельно, а дескрипторы дают возможность включить эти и другие сложные поведения с помощью одного простого API.
Как уже отмечалось, синтаксис декоратора, представленный в Python 2.4, дает более удобный способ объявления статических методов, но это просто синтаксическое удобство и ничего не меняет, как работают статические методы.
См. http://www.python.org/doc/2.2.3/whatsnew/sect-rellinks.html и http://users.rcn.com/python/download/Descriptor.htm для более подробной информации о классах и дескрипторах нового стиля.
Ответ 4
Гвидо всегда опасался добавления новых конструкций к языку. Когда были предложены статические методы, было показано, что вы уже могли это сделать (есть staticmethod()
decorator с 2.2), у вас просто не было синтаксического сахара для него.
Если вы читаете PEP, вы можете увидеть все обсуждение, которое добавляет что-то. Я, например, как этот подход. Это напоминает мне C
, поскольку нет лишних ключевых слов.
Когда новый синтаксис для декораторов, добавленных в Python 2.4, вы можете использовать существующие декораторы с более сильным синтаксисом.
Во всяком случае, они не так уж различны, если вам нужно поддерживать старую систему.
#>2.4
class MyClass(object):
@staticmethod
def mystaticmethod(params)
pass
return
#<2.4
class MyClass(object):
def mystaticmethod(params)
'''Static Method'''
pass
return
staticmethod(mystaticmethod)
Я бы рекомендовал добавить комментарий или docstring к статическому методу screaming, который является статическим методом.
Ответ 5
Начиная с Python 2.4, можно также использовать decorator, как в:
@staticmethod
def mystaticethod(params)
...
return
Но у меня нет никакого представления о генезисе этой функции, как реализовано на самом деле, на языке. Но опять же, я не голландский:-) Посмотрите ответ Майкла E в этом посте, касающийся позднего появления статических методов в эволюции Python.
BTW, при всей их простоте, как
@MyDeco
someObject
is merely "syntactic sugar" for
MyDeco(someObject)
декораторы могут использоваться для многих других интересных вещей!
Ответ 6
Статическая ситуация с методом в Python является довольно прямым следствием проектных решений первоклассное все и все является исполняемым выражением. Как утверждали другие, staticmethod стал доступен только с новой семантикой, разрешенной протоколом дескриптора Python 2.2 и синтаксически слаще украшали функции в Python 2.4. Там простая причина, почему статические методы получили так мало внимания - они никоим образом не расширяют возможности языка и делают синтаксис лишь немного лучше. Семантически они эквивалентны старым старым функциям. Вот почему они были реализованы только тогда, когда сила языка выросла настолько, чтобы сделать их реалистичными с точки зрения других языковых особенностей.
Ответ 7
Гвидо пишет блог История Python. Я думаю, что есть способ связаться с ним с просьбой расширить эту тему.
Ответ 8
Возможно, дизайн первоначально не предполагал, что статический метод необходим, когда функция может использоваться. Поскольку python не скрывал данные, поэтому действительно не нужны статические методы, а не использование классов в качестве пространств имен.