[Tutor] Using new style classes and __slots__

Kent Johnson kent37 at tds.net
Sun Sep 25 04:00:42 CEST 2005

Liam Clarke wrote:
> Thanks Kent. Just looking at that above recipe, I'm not too sure how
> the @ decorators work.
>>From what I understand, it defines would turn apply() into a function
> that returns the various get/sets?

OK, lets pick it apart a bit. Here is the recipe for defining a property:
class Example(object):
    def myattr():
        doc = """This is the doc string."""

        def fget(self):
            return self._value

        def fset(self, value):
            self._value = value

        def fdel(self):
            del self._value

        return property(**locals())

Looking at myattr(), it defines the four attributes that make a property - doc, fget, fset and fdel. So at the end of myattr(), locals() is a dictionary containing these four attributes. Then it calls property() and passes it locals() as keyword arguments. So the last line is the same as return property(doc=doc, fget=fget, fset=fset, fdel=fdel) which creates a normal property.

OK, now what does the @apply do? Well, it's a decorator, and in general
def myfunc():
  # etc

means the same thing as
def myfunc():
  # etc
myfunc = some_decorator(myfunc)

In other words the decorator is called with the function as an argument, and the return value of the function is bound to the name of the original function. So we have to know what apply(myattr) does. Actually, it just calls myattr(). So the net result is
myattr = myattr() i.e.
myattr = property(doc=doc, fget=fget, fset=fset, fdel=fdel)
which is what you would have done any way if you weren't trying to be so clever.

What does this recipe buy you? It puts the property function definitions into a separate namespace so they are not accessible as member functions, and it lets you reuse the names for them instead of having to invent new ones each time.
> Also found something interesting with property(), if it's called in
> __init__ you get
> <property object at 0x011598C8>
> whereas called outside __init__ it works normally.

Are you assigning the property to self or to the class? It might work if you assign to the class. But you will be recreating the properties for every instance.
> This is a hassle for me because I'm a lazy typist, so I've been using
> setattr() to pull attribute names out of a list. And the first
> argument setattr() requires is an object, and self doesn't work
> outside of a method, and using the class name leads to no attribute
> being set.

I don't understand this at all, can you give an example?
> Hmm, may have to learn even more about classes and their internals.

Yeah, it sounds like maybe a case for a metaclass.


> Regards,
> Liam Clarke
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> http://mail.python.org/mailman/listinfo/tutor

More information about the Tutor mailing list