0

Can somebody explain to me why, in the following code ext is reachable within the MP3File class, but not within its play method? Sorry for the short question, that is all I need to know.

class MP3File(AudioFile):
    ext = 'mp3'
    print(ext)

    def play(self):
        print(ext) #NameError: global name 'ext' is not defined
Startec
  • 12,496
  • 23
  • 93
  • 160

1 Answers1

1

ext is not a global, it is temporarily a local when the class is being created. From the class statement documentation:

The class’s suite is then executed in a new execution frame (see Naming and binding), using a newly created local namespace and the original global namespace. (Usually, the suite contains mostly function definitions.) When the class’s suite finishes execution, its execution frame is discarded but its local namespace is saved.

Emphasis mine. The local namespace then forms the class attributes.

By the time your MP3File.play() method is being called, that local namespace is long since gone; you cannot just refer to ext as if it still exists. It is now a class attribute instead!

You can address that attribute via the self reference to an instance. Unless the instance also has an ext attribute, the class attribute is found and returned instead:

def play(self):
    print(self.ext)

or you can find it on the class:

def play(self):
    print(MP3File.ext)
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • **"its execution frame is discarded but its local namespace is saved."** To me this makes it sound like the variable would be deleted altogether. Am I right that what is actually happening (strangely, to me) is that it transforms from a 'temporary local variable' to a class attribute with no sort of assignment necessary? – Startec Sep 13 '14 at 23:17
  • @Startec: the local names created in the execution frame are used as the attributes on the class object. The assignment has already taken place; it is just a question of using transforming the local namespace into a dictionary; e.g. enumerate the local names as keys, and their values as the associated values in the dictionary. – Martijn Pieters Sep 13 '14 at 23:19
  • @Startec: if you want to know more about that process, read [What is a metaclass in Python?](http://stackoverflow.com/q/100003) – Martijn Pieters Sep 13 '14 at 23:21