Как был выбран синтаксис для статических методов в Python?

Я работал с Python некоторое время, и я нахожу синтаксис для объявления методов как статических, чтобы быть своеобразным.

Будет объявлен обычный метод:

def mymethod(self, params) ... return 

Объявлен статический метод:

 def mystaticethod(params) ... return mystaticmethod = staticmethod(mystaticmethod) 

Если вы не добавляете статическую линию метода, компилятор жалуется на отсутствие себя.

Это очень сложный способ сделать что-то очень простое, что на других языках просто используйте ключевое слово и грамматику декларации. Может ли кто-нибудь рассказать мне об эволюции этого синтаксиса? Это просто потому, что классы добавлены в существующий язык?

Так как я могу перемещать линию staticmethod до более позднего класса, это также предполагает, что синтаксический анализатор работает над бухгалтерией.

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

5 Solutions collect form web for “Как был выбран синтаксис для статических методов в Python?”

Статические методы были добавлены в Python долго после того, как были классы (классы были добавлены очень рано, возможно, даже до 1.0, статические методы не отображались до примерно 2.0). Они были реализованы как модификация обычных методов – вы создаете объект статического метода из функции для получения статического метода, тогда как компилятор по умолчанию генерирует методы экземпляра.

Как и во многих вещах в Python, статические методы были введены, а затем уточнены по мере того, как люди использовали их и хотели лучшего синтаксиса. Первоначальный раунд был способом введения семантики без добавления нового синтаксиса к языку (и Python вполне устойчив к изменениям синтаксиса). Я не Гвидо, поэтому я не совсем уверен, что происходит в его голове, и это несколько спекулятивно, но Python имеет тенденцию двигаться медленно, постепенно развиваться и улучшать вещи, поскольку они приобретают больше опыта с ними (в частности, им не нравится добавлять что-то, пока они не выяснят правильный способ сделать это. Возможно, это и не объясняло, почему для статических методов с самого начала не было специального синтаксиса).

Однако, как указал mjv, теперь есть более простой способ: через некоторый синтаксический сахар, добавленный в 2.2 или 2.3 под названием «декораторы»:

 @staticmethod def mystaticmethod(params) ... return 

Синтаксис @staticmethod – это сахар для установки mystaticmethod = staticmethod(mystaticmethod) после определения метода.

voyager и adurdin делают хорошую работу между ними, объясняя, что произошло: с введением классов и дескрипторов нового стиля в Python 2.2 появились новые и глубокие семантические возможности – и наиболее очевидные полезные примеры (статические методы, методы класса , свойства) поддерживались встроенными типами дескрипторов без какого-либо нового синтаксиса (синтаксис @foo для декораторов был добавлен пару релизов позже, как только новые дескрипторы вполне доказали свою реальную полезность). Я не очень квалифицирован, чтобы направить Гвидо (где Тим Питерс, когда он вам нужен!), Но в то время я уже был комбатантом Python и участвовал в этих событиях, и я могу подтвердить, что это действительно то, что произошло.

наблюдение вояджера о том, что это напоминает ему о С, справедливо на цели: я давно утверждал, что Python захватывает больше «Духа С», чем любой из языков, которые имитировали синтаксис C (скобки, круглые скобки после if / while , и т.д). «Дух C» фактически описан в (ненормативной) части Обоснования стандарта ISO C и состоит из пяти принципов (ни один из которых не требует брекетов!), Из которых я утверждаю, что Python соответствует 4.5 (есть несколько видеороликов на сеть презентаций на «Python for Programmers», где я рассказываю об этом, если вам интересно).

В частности, Spirit of C «предоставляет только один способ выполнения операции» соответствует Zen of Python «Должен быть один – и желательно только один – простой способ сделать это» – и C и Python, я верю , являются единственными двумя широко распространенными языками для явного принятия такого конструктивного идеала единообразия и отсутствия избыточности (он идеален и не может быть разумно достигнут на 100% – например, если a и b являются целыми числами a + b и b + a ЛУЧШЕ было два одинаково очевидных способа получить свою сумму! -) – но цель – стремиться! -).

Статические методы в 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 для обычного метода, который по умолчанию используется для всех простых функций в атрибутах классов (это не совсем то, что происходит с поиском метода из экземпляра, но оно обрабатывает автоматическое «я», аргумент):

 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 для получения более подробной информации о новом стиле классов и дескрипторов.

Гвидо всегда опасался добавления новых конструкций на язык. Когда были предложены статические методы, было показано, что вы уже могли это сделать ( с 2,2 ) существует декоратор staticmethod() ), у вас просто нет синтаксического сахара.

Если вы читаете PEP, вы можете увидеть все обсуждение, которое добавляет что-то. Я, например, как этот подход. Это напоминает мне о том, что нет лишних ключевых слов.

Когда новый синтаксис для декораторов, добавленных в 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 к критическому статическому методу, который является статическим методом.

Статический метод ситуации в Python является довольно прямым следствием дизайнерских решений первоклассного всего, и все это исполняемый оператор . Как утверждали другие, staticmethod стал доступен только с новой семантикой, разрешенной протоколом дескриптора Python 2.2 и синтаксически слаще украшали функции в Python 2.4. Есть простая причина, по которой статические методы получили так мало внимания – они никак не расширяют возможности языка и делают синтаксис лишь немного лучше. Семантически они эквивалентны старым старым функциям. Вот почему они были реализованы только тогда, когда сила языка выросла настолько, чтобы сделать их реалистичными с точки зрения других языковых функций.

  • Исключение статической переменной Python
  • Зачем загружать статические файлы для каждого шаблона, даже если он расширяется?
  • Почему класс Python не распознает статическую переменную
  • STATIC_URL не определен в базовом шаблоне Django
  • Настройка STATIC_ROOT в Django 1.8
  • Правильный способ обработки статических файлов и шаблонов для Django на Heroku
  • Справка по приложению в статических файлах Django
  • Django - ссылки на статические файлы в шаблонах
  • Python - лучший язык программирования в мире.