views:

64

answers:

2

In python, I want to have a class attribute which is a dictionary with initialized values. I wrote the code like the below.

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

But when I try to run this code I met an error message with "NameError: name 'MetaDataElement' is not defined". Could you help me?

Thanks in advance.

A: 

First of all, you're using old-style classes. You should probably use new-style classes, like so:

class MetaDataElement(object):
    ...

Note the (object). Anyway, though, simply remove the MetaDataElement. when referring to the class attributes. This is what it'd look like when that's done:

class MetaDataElement(object):
    (MD_INVALID, MD_CATEGORY, MD_TAG) = range(3)
    mapInitiator2Type = {'!': MD_CATEGORY, 
                         '#': MD_TAG}
icktoofay
Maybe redism is writing in Python 3 and *is* using new-style classes. :)
EOL
@EOL: I wasn't aware that Python 3 used new-style classes by default. That's good to know.
icktoofay
Here is the reference: "Classic classes are gone." (http://docs.python.org/release/3.0.1/whatsnew/3.0.html#removed-syntax)
EOL
+1  A: 

You cannot refer to MetaDataElement while it is being constructed, since it does not yet exist. Thus,

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

fails because the very construction of mapInitiator2Type requires MetaDataElement to have attributes, which it does not yet have. You can think of your constants MD_INVALID, etc. as variables that are local to the construction of your class. This is why the following works, as icktoofay wrote:

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

However, you can refer to the class MetaDataElement in any yet un-interpreted piece of code, as in

    def method_of_MetaDataElement():
        print MetaDataElement.MD_TAG

You even have to refer to MetaDataElement, here, because MD_TAG is not a kind of local variable when method_of_MetaDataElement() is executed (MD_TAG was only defined as a kind of local variable during class construction). Once the class MetaDataElement is created, MD_TAG is simply a class attribute, which is why method_of_MetaDataElement() must refer to it as such.

EOL