Python - ссылка на имя класса изнутри тела класса - PullRequest
1 голос
/ 23 июля 2010

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

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

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

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

Ответы [ 2 ]

2 голосов
/ 23 июля 2010

Вы не можете ссылаться на 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() должен ссылаться на него как таковой.

0 голосов
/ 23 июля 2010

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

class MetaDataElement(object):
    ...

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

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