Issue 1921: Confusing Descrintro example (original) (raw)

Guido's document "Unifying types and classes in Python 2.2" (descrintro) contains a confusing example for metaclass newbies. <http://www.python.org/download/releases/2.2.3/descrintro/#metaclass_examples>

The example in question is autoprop, which uses the variable "name" in three different contexts. First, it is the name of the class being created. Second, it is used in a for loop to denote the keys of the class dict. And thirdly, it is used to denote substrings of a subset of those keys.

Upon my first encounter with the example, I found myself staring at the getattr and setattr lines in disbelief. I associated "name" as the parameter given to the init function.

I'd propose changing the first for-loop name to "member" or similar and the second to "propname" or "prop".

Furthermore, a modern version of the same example could use sets and set comprehensions instead of dict.keys(): props = {member[5:] for member in dict if member.startswith...}

I'm guessing you weren't ready for learning about metaclasses if you didn't get the fact that 'name' was the loop control variable in the two different loops. The example is only 11 lines long!

Still, I'm fine with the two suggested renames.

I'm not fine with rewriting the example using modern constructs, since it is part of the docs for Python 2.2. Perhaps the doc is still useful but then it should be first moved into the regular doc tree and then adapted to modern times (and we can't really release that version until 2.7 and 3.2 are released).

Unfortunately I do not have a checkout of the website handy any more (or I can't remember where I put it). Maybe one of the webmasters can make the suggested fixes?

The fixed code that I agree with is:

class autoprop(type): def init(cls, name, bases, dict): super(autoprop, cls).init(name, bases, dict) props = {} for member in dict.keys(): if member.startswith("get") or member.startswith("set"): props[member[5:]] = 1 for prop in props.keys(): fget = getattr(cls, "get%s" % prop, None) fset = getattr(cls, "set%s" % prop, None) setattr(cls, prop, property(fget, fset))