Class Variable Question

Alex Martelli aleaxit at yahoo.com
Wed Apr 11 05:56:07 EDT 2001


"Robert Johnson" <rjohnson at exotic-eo.com> wrote in message
news:3ad411ff$0$47987$e2e8da3 at nntp.cts.com...
>
> > Consider an *instance* of a std::map< std::string, std::string >, for
> > example.  You CAN "just add things on the fly" to it, can't you?  Isn't
> > it handy, indeed sometimes crucial, to be able to add any foo->bar
> > mapping entry to the class on the fly, as and if and when the need
> > arises, at runtime, rather than having to pre-declare all the set
> > of 'keys' that are going to be allowed and/or mandatory for all
> > instances of such a type...?
>
> I am not sure you understand the point I am trying to make here.  Even if
I

Probably not, since it appears to me that the only difference
(type-of-values apart) is in syntax-sugar.

> were to make a map with void* where the type of the object being stored
> becomes irrelevant, it still would not be what I am talking about.  The
only
> way to add anything to your mapInstance is to add strings like:
>
> mapInstance["Python"]="Is cool, please don't shoot me."

Yep, here you could only add _strings_ (with 'void*' you would
gain a bit more flexibility, but not much usefulness) -- other
compile-time-typesafe languages such as Java (if it had some
way to have constrained generics) would let you use 'Object'
as the value-type, so you could in fact add anything.


> I can't simply expand the object by adding new variables that have nothing
> to do with the laid-out definition of the map.  Once I instantiate the
map,
> I can't simply type "mapInstance.newVariable=5".

But that's just a syntax-sugar issue!  For most Python objects,
    mapInstance.newVariable = 5
boils down to nothing more than
    mapInstance.__dict__['newVariable'] = 5

You "expand the object" by adding new entries to the dictionary
it holds -- how is that different from being able to add new
entries to any other dictionary/mapping, except syntactically?

For object that DO define __setattr__, a closer semantic
equivalent is:
    mapInstance.__setattr__('newVariable', 5)
and again you could easily do basically the same thing in
C++ by adding a template-method __setattr__ to your class
(or in Java by adding a __setattr__ that takes 2 Object's).

Whatever the object then does as a result of that method
call is obviously up to the object; it's conventionally
_expected_ to somehow 'store' the 'value' so it can later be
'retrieved' using the 'name' -- just like, e.g., when
writing a C++ template I will _expect_ that calling
    foo.insert(std::makepair(bar,fum));
on a parameter object foo whose type I, template author,
do not know, will have it behave std::map-like, etc.


Does it strike you as ABSURD to be able to use
    foo.bar = fum
as a syntactic shorthand for a method-call
    foo.whatever(bar, fum)
?  Yet popular implementations of C++, such as Borland's
and Microsoft's, add such syntax-sugary features to the
standard C++ language (under name of 'properties'), and
assignment-as-shorthand-for-a-method-call is hardly an
alien concept to C++ (although it normally chooses to
'hook' it to the fully-solved LHS lvalue, absent extensions
such as those mentioned that optionally allow somewhat finer
granularity in such hooking).  In Python, you get somewhat
finer-grained 'hooking' of assign-to-attribute syntax, and
a runtime equivalent of C++'s template (generic programming,
in more general terms) philosophy of 'polymorphism by
signature matching'.  Why does such modest generalization
look or feel so alien to you?

To me, it looks like a typical case of "much ado about
nothing", also known as building mountains out of mole-
hills, I believe...


Alex






More information about the Python-list mailing list