Python – ссылка на имя класса изнутри тела класса

StackOverflow https://stackoverflow.com/questions/3315510

  •  27-09-2020
  •  | 
  •  

Вопрос

В Python я хочу иметь атрибут класса, словарь, с инициализированными значениями.Я написал этот код:

class MetaDataElement:
    (MD_INVALID, MD_CATEGORY, MD_TAG) = range(3)
    mapInitiator2Type = {'!':MetaDataElement.MD_CATEGORY, 
                         '#':MetaDataElement.MD_TAG}

Но когда я пытаюсь запустить этот код, я получаю сообщение об ошибке «NameError:имя «MetaDataElement» не определено».Не могли бы вы помочь мне?

Заранее спасибо.

Это было полезно?

Решение

Вы не можете ссылаться на MetaDataElement пока он строится, так как его еще нет.Таким образом,

class MetaDataElement:
    (MD_INVALID, MD_CATEGORY, MD_TAG) = range(3)
    mapInitiator2Type = {'!':MetaDataElement.MD_CATEGORY, 
                         '#':MetaDataElement.MD_TAG}

терпит неудачу, потому что сама конструкция mapInitiator2Type требует MetaDataElement иметь атрибуты, которых у него еще нет.Вы можете думать о своих константах MD_INVALID, и т. д.как переменные, локальные для конструкции вашего класса.Вот почему, как писал icktoofay, работает следующее:

class MetaDataElement:
    (MD_INVALID, MD_CATEGORY, MD_TAG) = range(3)
    mapInitiator2Type = {'!': MD_CATEGORY,  # MD_CATEGORY is like a local variable!
                         '#': MD_TAG}

Однако вы можете обратиться к классу MetaDataElement в любом еще неинтерпретированном фрагменте кода, например

    def method_of_MetaDataElement(self):
        print MetaDataElement.MD_TAG

Ты даже иметь ссылаясь на MetaDataElement, здесь, потому что MD_TAG не является своего рода локальной переменной, когда method_of_MetaDataElement() выполняется (MD_TAG был определен как своего рода локальная переменная только во время создания класса).Однажды класс MetaDataElement создано, MD_TAG это просто атрибут класса, поэтому method_of_MetaDataElement() должен относиться к нему как к таковому.

Другие советы

Прежде всего, вы используете классы старого стиля.Вероятно, вам следует использовать классы нового стиля, например:

class MetaDataElement(object):
    ...

Обратите внимание (object).В любом случае, просто удалите MetaDataElement. при обращении к атрибутам класса.Вот как это будет выглядеть, когда это будет сделано:

class MetaDataElement(object):
    (MD_INVALID, MD_CATEGORY, MD_TAG) = range(3)
    mapInitiator2Type = {'!': MD_CATEGORY, 
                         '#': MD_TAG}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top