Подкласс python доступа к переменной класса родительского

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

>>> class A(object): ... x = 0 ... >>> class B(A): ... y = x+1 ... Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 2, in B NameError: name 'x' is not defined >>> class B(A): ... y = Ax + 1 ... >>> Bx 0 >>> By 1 

Почему в определении я должен ссылаться на Ax, а не только на x? Это противоречит моей интуиции из переменных экземпляра, и поскольку я могу ссылаться на Bx после определения B.

  • Многопроцессорность Python - совместное использование сложного объекта
  • Сохранять данные Tf-Idf
  • Передача списка через url в django
  • Как сделать солнечный участок в R или Python?
  • текстовый блок python и текстовая классификация
  • У кого-нибудь есть «темный» файл схемы pycharm?
  • Передайте формулу в качестве параметра функции в python
  • Как установить заголовок приложения в Gnome Shell?
  • 2 Solutions collect form web for “Подкласс python доступа к переменной класса родительского”

    В Python тело класса выполняется в собственном пространстве имен до создания класса (после чего члены этого пространства имен становятся членами класса). Поэтому, когда интерпретатор достигает y = x + 1, класс B еще не существует в этой точке и, следовательно, не имеет родителя.

    Для получения дополнительной информации см. http://docs.python.org/reference/compound_stmts.html#class-definitions

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

    Каждый раз, когда вам нужен другой поиск, вы будете использовать квалифицированное имя, а не простое имя. Квалифицированные имена значительно более мощные, потому что поиск всегда может быть делегирован объектам, чьи атрибуты могут быть запрошены, и этот объект может реализовать любые правила поиска, в которых они нуждаются. В частности, в методе экземпляра внутри класса self.xэто способ попросить self.x искать имя атрибута 'x' – и в этом поиске он может делегировать классы, включая реализацию концепции наследования (и множественное наследование, порядок разрешения метода и т. д.).

    Тело класса (в отличие от тел методов, определенных в классе) выполняется как часть оператора class , прежде чем объект класса создается или его имя связано (в частности, до того, как какая-либо из баз была определена как основы, хотя эта последняя деталь никогда не имеет значения при обращении к барным именам, в любом случае! -).

    Итак, в вашем примере, в классе B , barename x просматривается с универсальными правилами – это локальное имя? Если нет, то он связан в любой внешней функции, в которой этот объем вложен? Если нет, то он связан как глобальный или встроенный? Если ни одно из вышеперечисленных вопросов, использующее указанное имя barename, вызывает исключение ошибки имени.

    Так как вам нужна другая последовательность поиска, чем правила поиска в barename универсально, то ясно, что вам нужно использовать квалифицированное имя, а не barename; и мгновенное отражение ясно покажет, что «один очевидный выбор» для квалифицированного имени, используемого для вашей цели, должен быть Ax так как именно там вы хотите, чтобы он был поднят (базы еще не были записаны в эта точка, в конце концов … это будет метакласс, обычно type , который будет делать привязки к основанию как часть своей работы, когда он вызывается после того, как тело класса будет исполнено! -).

    Некоторые люди так остро привязаны к другим «магическим» правилам поиска барменов, которые они просто не выдерживают, этот аспект Python (первоначально вдохновленный, я полагаю, Modula-3, малоизвестный язык, который очень хорошо рассматривается у теоретиков 'круги 😉 – нужно написать self.x в методе, чтобы указать, что x нужно искать на self а не использовать универсальные правила barename, например, диски таких людей батты.

    Мне нравится простота и универсальность правил поиска в barename, и я люблю использовать квалифицированные имена вместо barenames в любое время, когда хочу любую другую форму поиска … но тогда не секрет, что я безумно люблю Python (у меня есть свои собственные ворчания – например, global x как оператор всегда заставляет сканирование моего global.x , где я бы скорее написал global.x , т. global.x global было бы встроенным именем для «текущего исполняемого модуля», … Я люблю квалифицированные имена! -), не так ли? -)

    Python - лучший язык программирования в мире.