B
Bruno Desthuilliers
MonkeeSage a écrit :
No, I'm talking about the result of calling a.a - which is what a.a()
means !-)
Jordan, I of course understand what you mean - but the way you express
it is not coherent with how Python works. In Python, the expression
a.a() *is* the result of calling a.a, period.
which is the value of expression "a.a". Whether this expression evals to
a callable object or not, and wether this callable object is actually a
method object or not is another question, mostly unrelated with the
meaning of expression 'a.a'.
Still not. The fact that an attribute is callable doesn't make it a method.
Which standard definition ? Obviously not Python's standard definition
anyway !-)
No you don't. You know that a.a is callable, period.
<mode="stubborn">
Yes it does : they are all of kind 'object' !-)
Obviously not - but this is true for all known OOPL. Now from a
technical POV, there are no separate slots, no compiler-or-interpreter
special processing, nor nothing else special about 'methods', no special
type, etc - the storage and lookup mechanisms are *exactly* the same for
*all* attributes (leaving special features like __slots__ aside). All
the "magic" in 'methods' is handled by the way the function type
implements the descriptor protocol, and this can be reproduced by any
other type, because it's just *one* possible use of lookup hooks (+, in
this case, callable objects) - another possible use being the property
type. IOW, what makes the difference is the specific implementation of
the attribute's class, *not* the generic attribute storage/lookup mechanism.
This "common definition" is obviously not applicable to each and every
language - at least when it comes to implementation !-)
Mays I remind you that the OP question was about "how to distinguish
methods from attributes". And the answer is that given Python's object
model and implementation, there's no clear, definitive and unambiguous
way to do so.
The fact is that it does matter, because it's the lookup mechanism that
implements the hook used by functions to return methods when they are
used as class attributes. And it also matters because *all* this
behaviour can be reproduced without extending the function type nor
using the method type, so you can't even rely on typechecking to
distinguish a callable attribute from what is commonly known as a a method.
Still not. May I remind you that the class is a callable attribute of an
object ? And that when used as *instance* attributes, functions remain
plain functions ? And that a class attribute can be callable without
implementing the lookup hook that would yield a method object ?
This is exactly what I'm trying to explain here : in Python, callable
attribute != method.
By your definition, the class of an object is a method. I'll let you
think about it...
On Dec 8, 4:11 pm, Bruno Desthuilliers (snip)
You're talking about the result of calling a.a()
No, I'm talking about the result of calling a.a - which is what a.a()
means !-)
Jordan, I of course understand what you mean - but the way you express
it is not coherent with how Python works. In Python, the expression
a.a() *is* the result of calling a.a, period.
, I'm talking about
what the attribute "a" on the object "a" is.
which is the value of expression "a.a". Whether this expression evals to
a callable object or not, and wether this callable object is actually a
method object or not is another question, mostly unrelated with the
meaning of expression 'a.a'.
Which is a callable
attribute, which by definition is called a "method" in the standard
sense [1].
Still not. The fact that an attribute is callable doesn't make it a method.
You can make a distinction between a "method object" and
"any other possible callable object," but I wasn't using such a
distinction, I was using the standard definition.
Which standard definition ? Obviously not Python's standard definition
anyway !-)
So my point holds.
When you see a.a(), because of pythons calling convention "()" you
know that "a" is a method of object "a".
No you don't. You know that a.a is callable, period.
The point is that just because the attributes are "looked up the same
way" or whatever, doesn't make them the same *kind* of attribute.
<mode="stubborn">
Yes it does : they are all of kind 'object' !-)
To
say that all attributes are the same in python muddies the water. They
are the same in a generic sense that they are attributes, but not in
their particular qualities.
Obviously not - but this is true for all known OOPL. Now from a
technical POV, there are no separate slots, no compiler-or-interpreter
special processing, nor nothing else special about 'methods', no special
type, etc - the storage and lookup mechanisms are *exactly* the same for
*all* attributes (leaving special features like __slots__ aside). All
the "magic" in 'methods' is handled by the way the function type
implements the descriptor protocol, and this can be reproduced by any
other type, because it's just *one* possible use of lookup hooks (+, in
this case, callable objects) - another possible use being the property
type. IOW, what makes the difference is the specific implementation of
the attribute's class, *not* the generic attribute storage/lookup mechanism.
Like saying "all humans are the same" --
yes, in a general sense of being human. But to leave it at that is not
very helpful.
[1] http://en.wikipedia.org/wiki/Method_(computer_science)
The second is whatever the lookup mechanism will yield for this name.
You're wrong. Python's "methods" are thin wrappers around an instance
(or class) and a function. These wrappers are "built" *at lookup time*
by the __get__ method of the function object itself when it's looked up
as an attribute of a class, thanks to the lookup mechanism and the
descriptor protocol.
Now the fact that an attribute is callable doesn't make it a "method".
Also, anyone can implement it's own callable type that will act as a
true function - that is, implement the descriptor protocol to return a
wrapper around the instance or class and the callable - without
necessarily yielding an instance of types.MethodType. This is all fairly
trivial.
Again, I am using the common definition.
This "common definition" is obviously not applicable to each and every
language - at least when it comes to implementation !-)
Mays I remind you that the OP question was about "how to distinguish
methods from attributes". And the answer is that given Python's object
model and implementation, there's no clear, definitive and unambiguous
way to do so.
I understand that you can
make an attribute callable in different ways than just the standard
machinery of "def symbol(self):" (those other techniques are what I
was referring to above by "metaprogramming"). But how it is made
callable doesn't matter (nor does how it is looked up).
The fact is that it does matter, because it's the lookup mechanism that
implements the hook used by functions to return methods when they are
used as class attributes. And it also matters because *all* this
behaviour can be reproduced without extending the function type nor
using the method type, so you can't even rely on typechecking to
distinguish a callable attribute from what is commonly known as a a method.
Once it is
callable, it fits the defintion of "method" I'm using.
Still not. May I remind you that the class is a callable attribute of an
object ? And that when used as *instance* attributes, functions remain
plain functions ? And that a class attribute can be callable without
implementing the lookup hook that would yield a method object ?
In future, I'll
try to be clear when I'm referring to something python specific or to
a general CS concept.
"Silly" in the sense that in this context, they only serve to show
that TIMTOWTDI, but don't actually change a callable attribute from
being a callable attribute ("method" in the general CS sense)
This is exactly what I'm trying to explain here : in Python, callable
attribute != method.
to being
some magical "something else".
For the purpose of distinguishing an
object variable (non-callable attribute) and an object method
(callable attribute), they don't add anything.
By your definition, the class of an object is a method. I'll let you
think about it...