2010-07-23 4 views
1

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

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

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

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

ответ

2

Вы не можете обратиться к 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

Последний пример может быть написан с помощью 'self.MD_TAG', что позволяет избежать необходимости обращаться к классу имя. – Marcin

+0

@Marcin: 'self.MD_TAG' также является возможностью, но это не эквивалентно' MetaDataElement.MD_TAG', если 'MetaDataElement' является подклассом (подклассы могут перезаписывать' MD_TAG'). Оба действительны, но выбор один зависит от ситуации. – EOL

+0

Честно говоря, я думаю, что, вероятно, неправильно использовать методы, чтобы запретить подклассам возможность с пользой изменять членов класса, поэтому я бы рекомендовал использовать 'self', если только для этого не существует конкретной причины. – Marcin

0

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

class MetaDataElement(object): 
    ... 

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

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

Возможно, что перерисовка написана в Python 3 и * is * использует классы нового стиля. :) – EOL

+0

@EOL: Я не знал, что Python 3 по умолчанию использовал классы нового стиля. Это хорошо знать. – icktoofay

+0

Вот ссылка: «Классические классы ушли». (http://docs.python.org/release/3.0.1/whatsnew/3.0.html#removed-syntax) – EOL

Смежные вопросы