Does Python really follow its philosophy of "Readability counts"?

Luis Zarrabeitia kyrie at uh.cu
Wed Jan 14 12:23:58 EST 2009


On Wednesday 14 January 2009 11:45:46 am Paul Rubin wrote:
> Luis Zarrabeitia <kyrie at uh.cu> writes:
> > Why don't you do it backwards?
> > You *can* implement a metaclass that will remove the dynasmism from its
> > instances. Do it - I can give you a starting point if you wish.
>
> That's kind of interesting, how does it work?

Proof of concept, that breaks on inheritance (can't call 'super'), but it took 
me just a few minutes to cook. If you aren't that paranoid, you could get rid 
of the 'currentframe' and 'code' hacks. This creates a class "MyClass" which 
instances cannot be modified. I once gave my students the homework of 
creating a metaclass that would type-check all the assignments to its 
members - so that the types wouldn't change.

========
import inspect

class ImmutableType(type):
    def __init__(self, *args, **kwds):
        super(ImmutableType, self).__init__(*args, **kwds)
        initmethod = self.__init__.im_func
        def setattr(instance, attr, value):
            callee = inspect.currentframe(1)          #letting the initializer
            if callee.f_code is initmethod.func_code: #initialize the object
                super(self, instance).__setattr__(attr, value)
            else:
                raise Exception("Object is immutable")
        self.__setattr__ = setattr  # Heh, I'm adding a dynamic attribute :D


class MyClass(object):
    __metaclass__ = ImmutableType
    a = 5
    def __init__(self, value):
        print "assigning b"
        self.b = value
        print self.b

m = MyClass("can't change")

print m.a, m.b  # these work
m.b = 6         # and these dont.
m.c = 8
==========


> > But most of us are very happy with the dynamic nature of python... I
> > chose python _because_ of it.
>
> I like it too, since it is indispensable in some situations.  But,
> those situations are uncommon enough that I don't mind typing a few
> extra keystrokes to turn the dynamism on.

I find the opposite to be true.
I _usually_ want the dynamism. Even if I'm not using it - I rely on the 
dynamism to be there for when I need it. 

> > Btw, for performance, there is __slots__,
>
> That is a good point, we somehow lost sight of that in this thread.
>
> > with the side-effect that it forbids attribute creation 'on the
> > fly'.
>
> I have had the impression that this is a somewhat accidental side
> effect and shouldn't be relied on.

Yes, accidental side effect.

But I see no _necessary_ harm on tacking extra attributes to an existing 
object - specially if you are going to use them pretty close to the creation. 
I use them, a lot, specially when writing decorators... Many times I just 
want to 'mark' the decorated functions so I can inspect those marks later. 
I'd rather have a semi-private namespace for each pair ([group of]calling 
function[s], object), but it is way easier (and so far, maintanable) to just 
add an appropriately named dynamic attribute to the object.

Of course there can be harm - but the fault lies on the user and not the tool. 
I specially dislike that I can't add dynamic attributes to an object().

-- 
Luis Zarrabeitia (aka Kyrie)
Fac. de Matemática y Computación, UH.
http://profesores.matcom.uh.cu/~kyrie



More information about the Python-list mailing list