Гарантируется ли определение "__module__" во время создания класса?

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

class Foo(object):
    class_name = __module__.replace('_', '-')

Для меня это выглядело действительно странно (__module__, что это?), поэтому я пошел и посмотрел на модель python . Быстрый поиск показывает, что __module__ является свойством объектов класса и объектов функций. Однако в глобальном пространстве имен нет __module__ (как это легко проверить, просто попробовав посмотреть на него и наблюдая NameError, который будет...).

Я решил записать это на конкретное поведение, но в качестве последней проверки я решил протестировать другие реализации, которые мне удобны. Оказывается, этот код выполняется с помощью 1

  • Cpython 2.7.6
  • Cpython 3.4.0
  • jython 2.5.3
  • PyPy 2.2.1 (Python 2.7.3)

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

1 Все linux, но я сомневаюсь, что это важно...

Ответ 1

Что определяет документация, так это то, что классы будут иметь атрибут __module__. Кажется, что CPython делает это так, что он определяет локальную переменную __module__ в начале блока класса. Затем эта переменная становится атрибутом класса, как и любая другая переменная, определенная там.

Я не могу найти документацию о том, что __module__ должен быть определен таким образом. В частности, я не могу найти какую-либо документацию, явно указывающую, что атрибут должен определяться как локальная переменная в кубе класса, вместо того, чтобы назначаться как атрибут класса на более позднем этапе создания класса. В этом ответе на другой вопрос упоминается, что он работает таким образом и показывает, как он появляется в байте-коде. Был ошибка Jython, которую они исправили, заставив его работать так же, как CPython.

Я предполагаю, что это деталь реализации CPython, перенесенная на другие реализации. Насколько я могу судить, документация на самом деле не говорит, что __module__ должен быть доступен внутри тела класса, только после этого объекта класса.