Distinguishing attributes and methods

MonkeeSage MonkeeSage at gmail.com
Mon Dec 10 08:46:58 EST 2007


On Dec 10, 7:19 am, Bruno Desthuilliers <bruno.
42.desthuilli... at wtf.websiteburo.oops.com> wrote:
> MonkeeSage a écrit :
>
> > It seems that I've got a short-circuit somewhere here. I understand
> > that everything is an object and the the storage/lookup system is
> > object-agnostic, and that it is only the descriptors (or "tags" as I
> > called them generically)
>
> "descriptor" is a protocol - an interface if you prefer. It's a way for
> a class attribute to hook into the lookup mechanism, and it's
> implemented by the property type - to provide a basic support for
> computed attributes - and the function type - to provide the machinery
> that turns a function into a method.
>
> > that determine how an attribute is bound,
> > whether it is bound at all, whether it is even callable,
>
> An object is callable if it implement the __call__ method (for the
> commonly admitted definition of 'method' !-).
>
> > and so forth.
> > So, when I say that all callable attributes (or to be more precise,
> > all callable attributes bound to objects other than toplevel)
>
> You mean "other than a module" ?
>
> > are
> > "methods," what am I missing?
>
> All callable attributes that are either bound to an instance or don't
> implement the descriptor protocol the way the function type do.
>
> > You said "the difference [between a callable attribute and a method]
> > is the specific implementation of the attribute's class"...but this
> > almost sounds like type-by-primitive
>
> It isn't.
>
> > (a method is a method when it
> > derives from a certain base class), or type-by-behavior (a method is a
> > method when it behaves in a certain way, e.g., responds in a certain
> > way to a query).
>
> Bingo.
>
> > Is this correct? Shouldn't it be type-by-capability/
> > interface--i.e., it implements the protocol of a callable, therefore,
> > formally, it is not meaningfully different from any other callable
> > (quacks like a duck and all)?
>
> The answer is in how the function type implements the descriptor
> protocol. For an attribute to "become" a method when looked up, this
> attribute has to implement the descriptor protocol so that it's __get__
> method returns either a BoundMethod (or any equivalent) when looked up
> on the instance and an UnboundMethod (or any equivalent) when looked up
> on the class (I'll save you the details about classmethods etc).
>
> Now since the method type is mostly trivial to implement, the fact that
> an attribute lookup doesn't return an instance of Method doesn't
> necessarily imply it's not one - so the truth is that an attribute is a
> method if it behaves like one !-)
>
> > I guess what I'm asking is, in what way is a "method" (or "function")
>
> Python's 'methods' are really thin wrappers around an object, it's class
> and a function. In the common use case, one of these wrappers is
> instanciated each time you lookup a function that's a class attributes.
>
> > semantically different from a home-brewed callable I concoct and bind
> > to an object (or toplevel)? What is the distinction that I'm missing?
>
> Implement your own callable that doesn't implement the descriptor
> protocol, bind it to a class, instanciate your class, lookup this
> attribute. You'll get the original attribute, not a method. Or bind a
> function to an *instance*, and look it up - here again, you wont get a
> method, but the original function object.
>
> Now you can of course label this a static method if you want !-)
>
> If you want a custom callable to be usable as a method, you have to
> implement the descriptor protocol like the function type do.
>
> > Ps. wrt your last comment, isn't a class object in essence a factory
> > method?
>
> Not quite - even if you can use it that way. In fact, the real factory
> method is the __new__ method of the class - that is, the proper constructor.
>
> A class object is an object that is responsible for:
> * creating instances of itself (and as such, it is indeed a factory -
> but a factory object, not a factory method)
> * providing class attributes and mro to these instances (lookup rules
> here: a name not found in the instance's __dict__ will be looked up in
> the class, then in classes in the mro - unless of course the class
> implements __getattr__ or __getattribute__, in which case all bets are
> off).
>
> caveat : all this describes the 'new-style' object model. The 'classic'
> ('old-style') object model works a bit differently.
>
> > Regards,
> > Jordan

Thank you kindly Bruno. You're answers have been very informative. I
thought I understand how python was operating, but I see that I have
some misconceptions. I honestly did read through the reference manual
when I started learning python a couple years ago, but I'm not the
most patient person by nature, and it seems that I was so happy with a
shiny new language, that I imported some foreign concepts into the
picture and glossed over many of the details of pythons object model.
I'm going to give the "Data Model" section a thorough going-over
again, and try to pay more attention this time(!) ;)

Just as a side-note, it's interesting that even through my
misunderstandings I've been able to use python to great effect (I've
translated several fairly complex apps to python, using decorators,
CPS and other fairly "advanced" techniques, and it "Just Worked").
Heh. Nice language. :)

Anyway, thanks again for your time an patience.

Regards,
Jordan



More information about the Python-list mailing list