471,310 Members | 1,409 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,310 software developers and data experts.

Distinguishing attributes and methods

Hi,

With properties, attributes and methods seem very similar. I was
wondering what techniques people use to give clues to end users as to
which 'things' are methods and which are attributes. With ipython, I
use tab completion all the time, but I can rarely tell from the names
alone whether it is an attribute or method.

Tips? Ideas? Best practices?

Here is one idea: Ipython should color-code the tab completion based
on attributes and methods.
Dec 8 '07 #1
26 1749
On Fri, 07 Dec 2007 23:19:40 -0800, tjhnson wrote:
With properties, attributes and methods seem very similar. I was
wondering what techniques people use to give clues to end users as to
which 'things' are methods and which are attributes.
Methods are attributes. So the decision is easy -- everything on an
object is an attribute. ;-)

Ciao,
Marc 'BlackJack' Rintsch
Dec 8 '07 #2
On Dec 8, 2:10 am, Marc 'BlackJack' Rintsch <bj_...@gmx.netwrote:
On Fri, 07 Dec 2007 23:19:40 -0800, tjhnson wrote:
With properties, attributes and methods seem very similar. I was
wondering what techniques people use to give clues to end users as to
which 'things' are methods and which are attributes.

Methods are attributes. So the decision is easy -- everything on an
object is an attribute. ;-)

Ciao,
Marc 'BlackJack' Rintsch
I think he means callable attributes (methods) and non-callable
attributes (variables).

Regards,
Jordan
Dec 8 '07 #3
On Sat, 08 Dec 2007 00:34:06 -0800, MonkeeSage wrote:
I think he means callable attributes (methods) and non-callable
attributes (variables).
But not every callable attribute is a method.

Ciao,
Marc 'BlackJack' Rintsch
Dec 8 '07 #4
On Dec 8, 6:50 am, Marc 'BlackJack' Rintsch <bj_...@gmx.netwrote:
On Sat, 08 Dec 2007 00:34:06 -0800, MonkeeSage wrote:
I think he means callable attributes (methods) and non-callable
attributes (variables).

But not every callable attribute is a method.

Ciao,
Marc 'BlackJack' Rintsch
I swear, you dynamic programmers and your metaprogramming
tomfoolery! :P

Regards,
Jordan
Dec 8 '07 #5
MonkeeSage a écrit :
On Dec 8, 2:10 am, Marc 'BlackJack' Rintsch <bj_...@gmx.netwrote:
>>On Fri, 07 Dec 2007 23:19:40 -0800, tjhnson wrote:
>>>With properties, attributes and methods seem very similar. I was
wondering what techniques people use to give clues to end users as to
which 'things' are methods and which are attributes.

Methods are attributes. So the decision is easy -- everything on an
object is an attribute. ;-)

Ciao,
Marc 'BlackJack' Rintsch


I think he means callable attributes (methods) and non-callable
attributes (variables).
callable attributes are not necessarily methods, and are still
'variables' anyway.
Dec 8 '07 #6
On Dec 8, 12:56 pm, Bruno Desthuilliers
<bdesth.quelquech...@free.quelquepart.frwrote:
MonkeeSage a écrit :
On Dec 8, 2:10 am, Marc 'BlackJack' Rintsch <bj_...@gmx.netwrote:
>On Fri, 07 Dec 2007 23:19:40 -0800, tjhnson wrote:
>>With properties, attributes and methods seem very similar. I was
wondering what techniques people use to give clues to end users as to
which 'things' are methods and which are attributes.
>Methods are attributes. So the decision is easy -- everything on an
object is an attribute. ;-)
>Ciao,
Marc 'BlackJack' Rintsch
I think he means callable attributes (methods) and non-callable
attributes (variables).

callable attributes are not necessarily methods, and are still
'variables' anyway.
I think it muddies the water to say that a.a() and a.a are the same
thing--obviously they are not. In the common case, the first is a
method, and the second is a variable. Yes, you can do silly stuff,
such that this rule will not hold, but in general it does. Or am I
wrong?

Regards,
Jordan
Dec 8 '07 #7
On Sat, 08 Dec 2007 11:44:36 -0800, MonkeeSage wrote:
On Dec 8, 12:56 pm, Bruno Desthuilliers
>callable attributes are not necessarily methods, and are still
'variables' anyway.

I think it muddies the water to say that a.a() and a.a are the same
thing--obviously they are not. In the common case, the first is a
method, and the second is a variable.
No, the first is a call of `a.a` while the second is just referencing
`a.a`. And `a.a` is a "variable" no matter if it refers to a callable or
not. Variables are name to object bindings and methods are objects.

Ciao,
Marc 'BlackJack' Rintsch
Dec 8 '07 #8
On Dec 8, 4:19 am, tjhn...@gmail.com wrote:
With properties, attributes and methods seem very similar. I was
wondering what techniques people use to give clues to end users as to
which 'things' are methods and which are attributes.
Methods are verbs, attributes are nouns :)

--
Roberto Bonvallet
Dec 8 '07 #9
On Dec 8, 7:44 pm, MonkeeSage <MonkeeS...@gmail.comwrote:
I think it muddies the water to say that a.a() and a.a are the same
thing--obviously they are not.
A thing is not what it is;
A thing is what it does.
This is the Way of the Duck.

-- Basho (in his "3 extra syllables" phase)
Dec 8 '07 #10
On Dec 8, 2:51 pm, Glenn Hutchings <zond...@googlemail.comwrote:
On Dec 8, 7:44 pm, MonkeeSage <MonkeeS...@gmail.comwrote:
I think it muddies the water to say that a.a() and a.a are the same
thing--obviously they are not.

A thing is not what it is;
A thing is what it does.
This is the Way of the Duck.

-- Basho (in his "3 extra syllables" phase)
Bah. Type-by-behavior never impressed me much. And I still think that
a.a is semantically different from a.a() in python.

Regards,
Jordan
Dec 8 '07 #11
MonkeeSage a écrit :
On Dec 8, 12:56 pm, Bruno Desthuilliers
<bdesth.quelquech...@free.quelquepart.frwrote:
>>MonkeeSage a écrit :

>>>On Dec 8, 2:10 am, Marc 'BlackJack' Rintsch <bj_...@gmx.netwrote:
>>>>On Fri, 07 Dec 2007 23:19:40 -0800, tjhnson wrote:
>>>>>With properties, attributes and methods seem very similar. I was
>wondering what techniques people use to give clues to end users as to
>which 'things' are methods and which are attributes.
>>>>Methods are attributes. So the decision is easy -- everything on an
object is an attribute. ;-)
>>>>Ciao,
Marc 'BlackJack' Rintsch
>>>I think he means callable attributes (methods) and non-callable
attributes (variables).

callable attributes are not necessarily methods, and are still
'variables' anyway.


I think it muddies the water to say that a.a() and a.a are the same
thing--obviously they are not.
Indeed. a.a yields the object bound to name 'a' in object a, while a.a()
yields the value returned by calling the object bound to name 'a' in
object a.
In the common case, the first is a
method,
Nope, it's the value returned by the call to a callable - remember that
in Python, the parens are the call operator, so the expression a.a()
evals to the value returned by the call to a.a - which is either the
method object returned by the collaboration of the lookup mechanism and
the descriptor protocol or any other possible callable object bound to
that name or returned by the lookup mechanism for that name.
and the second is a variable.
The second is whatever the lookup mechanism will yield for this name.
Yes, you can do silly stuff,
such that this rule will not hold, but in general it does. Or am I
wrong?
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.

And note that none of the two above cases are necessarily "silly".
Python exposes most of it's object model so you can hook into it and
taylor it to your needs. This results in some constructs that may seem
weird at first, but make sens once you understand them and learn to use
them.
Dec 8 '07 #12
MonkeeSage a écrit :
On Dec 8, 2:51 pm, Glenn Hutchings <zond...@googlemail.comwrote:
>>On Dec 8, 7:44 pm, MonkeeSage <MonkeeS...@gmail.comwrote:

>>>I think it muddies the water to say that a.a() and a.a are the same
thing--obviously they are not.

A thing is not what it is;
A thing is what it does.
This is the Way of the Duck.

-- Basho (in his "3 extra syllables" phase)


Bah. Type-by-behavior never impressed me much. And I still think that
a.a is semantically different from a.a() in python.
It is indeed and very obviously semantically different, and no one said
it wasn't. The first is an attribute lookup, the second is an attribute
lookup followed by a call. Now this doesn't make the attribute lookup
part different in both cases...
Dec 8 '07 #13
In article <47***********************@news.free.fr>,
Bruno Desthuilliers <bd*****************@free.quelquepart.frwrote:
MonkeeSage a écrit :
On Dec 8, 2:51 pm, Glenn Hutchings <zond...@googlemail.comwrote:
>On Dec 8, 7:44 pm, MonkeeSage <MonkeeS...@gmail.comwrote:
I think it muddies the water to say that a.a() and a.a are the same
thing--obviously they are not.

A thing is not what it is;
A thing is what it does.
This is the Way of the Duck.

-- Basho (in his "3 extra syllables" phase)

Bah. Type-by-behavior never impressed me much. And I still think that
a.a is semantically different from a.a() in python.

It is indeed and very obviously semantically different, and no one said
it wasn't. The first is an attribute lookup, the second is an attribute
lookup followed by a call. Now this doesn't make the attribute lookup
part different in both cases...
There are a very few corner cases were you can leave the ()'s out. For
example, you can do;

raise Exception

or

raise Exception()

but stuff like that is very much a wart in the language syntax.
Dec 9 '07 #14
Roy Smith a écrit :
In article <47***********************@news.free.fr>,
Bruno Desthuilliers <bd*****************@free.quelquepart.frwrote:

>>MonkeeSage a écrit :
(snip)
>>>Bah. Type-by-behavior never impressed me much. And I still think that
a.a is semantically different from a.a() in python.

It is indeed and very obviously semantically different, and no one said
it wasn't. The first is an attribute lookup, the second is an attribute
lookup followed by a call. Now this doesn't make the attribute lookup
part different in both cases...


There are a very few corner cases were you can leave the ()'s out.
You can leave them out wherever you want - it's just that it won't do
the same thing !-)
For
example, you can do;

raise Exception

or

raise Exception()
The context is somewhat different...
but stuff like that is very much a wart in the language syntax.
The syntax is

raise [<expression>[, <expression>,[ <expression>]]]

which can be used as either

raise <type>[, <value>[, <traceback>]]

or

raise <instance>[, None[, <traceback>]]
http://docs.python.org/ref/raise.html

You can call it a wart, but at least it's a well defined one - that is,
the first expression must eval to either an Exception type or an
Exception instance. So the 'optional' use of the call operator here has
nothing to do with it's mandatory use to actually call a function.
Dec 9 '07 #15
On Dec 8, 4:11 pm, Bruno Desthuilliers
<bdesth.quelquech...@free.quelquepart.frwrote:
MonkeeSage a écrit :
On Dec 8, 12:56 pm, Bruno Desthuilliers
<bdesth.quelquech...@free.quelquepart.frwrote:
>MonkeeSage a écrit :
>>On Dec 8, 2:10 am, Marc 'BlackJack' Rintsch <bj_...@gmx.netwrote:
>>>On Fri, 07 Dec 2007 23:19:40 -0800, tjhnson wrote:
>>>>With properties, attributes and methods seem very similar. I was
wondering what techniques people use to give clues to end users as to
which 'things' are methods and which are attributes.
>>>Methods are attributes. So the decision is easy -- everything on an
object is an attribute. ;-)
>>>Ciao,
Marc 'BlackJack' Rintsch
>>I think he means callable attributes (methods) and non-callable
attributes (variables).
>callable attributes are not necessarily methods, and are still
'variables' anyway.
I think it muddies the water to say that a.a() and a.a are the same
thing--obviously they are not.

Indeed. a.a yields the object bound to name 'a' in object a, while a.a()
yields the value returned by calling the object bound to name 'a' in
object a.
In the common case, the first is a
method,

Nope, it's the value returned by the call to a callable - remember that
in Python, the parens are the call operator, so the expression a.a()
evals to the value returned by the call to a.a - which is either the
method object returned by the collaboration of the lookup mechanism and
the descriptor protocol or any other possible callable object bound to
that name or returned by the lookup mechanism for that name.
You're talking about the result of calling a.a(), I'm talking about
what the attribute "a" on the object "a" is. Which is a callable
attribute, which by definition is called a "method" in the standard
sense [1]. 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. So my point holds.
When you see a.a(), because of pythons calling convention "()" you
know that "a" is a method of object "a".

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. 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. 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_...ter_science%29
and the second is a variable.

The second is whatever the lookup mechanism will yield for this name.
Yes, you can do silly stuff,
such that this rule will not hold, but in general it does. Or am I
wrong?

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. 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). Once it is
callable, it fits the defintion of "method" I'm using. In future, I'll
try to be clear when I'm referring to something python specific or to
a general CS concept.
And note that none of the two above cases are necessarily "silly".
Python exposes most of it's object model so you can hook into it and
taylor it to your needs. This results in some constructs that may seem
weird at first, but make sens once you understand them and learn to use
them.
"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) 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.

Regards,
Jordan
Dec 9 '07 #16
Op Sun, 09 Dec 2007 12:44:46 -0800, schreef MonkeeSage:
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. 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. 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.
Well, I guess Python is a language for human being... ;-)
To conclude this discussion:

* in Python, methods are attributes
* in Ruby, attributes are methods
--
JanC
Dec 10 '07 #17
On Sun, 09 Dec 2007 12:44:46 -0800, MonkeeSage wrote:
On Dec 8, 4:11 pm, Bruno Desthuilliers
<bdesth.quelquech...@free.quelquepart.frwrote:
>MonkeeSage a écrit :
You're talking about the result of calling a.a(), I'm talking about
what the attribute "a" on the object "a" is. Which is a callable
attribute, which by definition is called a "method" in the standard
sense [1]. 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. 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 know that. It's only a method of object `a` if it is really
a method bound to object `a` and not just a "data attribute" that happens
to be callable.
Again, I am using the common definition. 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). Once it is
callable, it fits the defintion of "method" I'm using. In future, I'll
try to be clear when I'm referring to something python specific or to
a general CS concept.
Your definition of "method" is a bit odd then. The general CS sense of
"method" requires the method to be bound to the object and not just be a
random callable. Let's see an example:

In [469]: a = collections.defaultdict(int)

In [470]: callable(a.default_factory)
Out[470]: True

In [471]: a.default_factory(42)
Out[471]: 42

`a.default_factory` is callable but hardly a method of `a` or `defaultdict`
but a "data attribute" that happens to be callable.

Ciao,
Marc 'BlackJack' Rintsch
Dec 10 '07 #18
MonkeeSage a écrit :
On Dec 8, 4:11 pm, Bruno Desthuilliers
(snip)
>>I think it muddies the water to say that a.a() and a.a are the same
thing--obviously they are not.
Indeed. a.a yields the object bound to name 'a' in object a, while a.a()
yields the value returned by calling the object bound to name 'a' in
object a.
>>In the common case, the first is a
method,
Nope, it's the value returned by the call to a callable - remember that
in Python, the parens are the call operator, so the expression a.a()
evals to the value returned by the call to a.a - which is either the
method object returned by the collaboration of the lookup mechanism and
the descriptor protocol or any other possible callable object bound to
that name or returned by the lookup mechanism for that name.

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' !-)
</mode>
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_...ter_science%29

>>and the second is a variable.
The second is whatever the lookup mechanism will yield for this name.
>>Yes, you can do silly stuff,
such that this rule will not hold, but in general it does. Or am I
wrong?
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.
>And note that none of the two above cases are necessarily "silly".
Python exposes most of it's object model so you can hook into it and
taylor it to your needs. This results in some constructs that may seem
weird at first, but make sens once you understand them and learn to use
them.

"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...
Dec 10 '07 #19
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) that determine how an attribute is bound,
whether it is bound at all, whether it is even callable, 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) are
"methods," what am I missing?

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 (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). 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)?

I guess what I'm asking is, in what way is a "method" (or "function")
semantically different from a home-brewed callable I concoct and bind
to an object (or toplevel)? What is the distinction that I'm missing?

Ps. wrt your last comment, isn't a class object in essence a factory
method?

Regards,
Jordan
Dec 10 '07 #20
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
Dec 10 '07 #21
On Mon, 10 Dec 2007 03:56:10 -0800, MonkeeSage wrote:
So, when I say that all callable attributes (or to be more precise, all
callable attributes bound to objects other than toplevel) are "methods,"
what am I missing?
Everything that isn't a method but is callable.

class Callable(object):
def __call__(self):
return oct(id(self))
class Foo(object):
aclass = type('Parrot', (object,), {})
atype = int
ainstance = Callable()
afunction = None # this is tricky...
def __init__(self): # a method
self.afunction = lambda n: n+1

--
Steven
Dec 10 '07 #22
On Dec 10, 7:19 am, Bruno Desthuilliers <bruno.
42.desthuilli...@wtf.websiteburo.oops.comwrote:
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
Dec 10 '07 #23
MonkeeSage a écrit :
On Dec 10, 7:19 am, Bruno Desthuilliers <bruno.
(snip)
I'm going to give the "Data Model" section a thorough going-over
again, and try to pay more attention this time(!) ;)
Also make sure you read the docs about new-style classes, the descriptor
protocol and metaclasses.
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. :)
Indeed !-)
Anyway, thanks again for your time an patience.
Thanks *you* for your patience - I'm certainly not the best teacher here !-)
Dec 10 '07 #24
Jan Claeys a écrit :
Op Sun, 09 Dec 2007 12:44:46 -0800, schreef MonkeeSage:

>>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. 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. 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.


Well, I guess Python is a language for human being... ;-)
To conclude this discussion:

* in Python, methods are attributes
* in Ruby, attributes are methods
And this is probably the most sensible post in this thread !-)
Dec 10 '07 #25
MonkeeSage <Mo********@gmail.comwrote:
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) that determine how an attribute is bound,
whether it is bound at all, whether it is even callable, 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) are
"methods," what am I missing?

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 (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). 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)?

I guess what I'm asking is, in what way is a "method" (or "function")
semantically different from a home-brewed callable I concoct and bind
to an object (or toplevel)? What is the distinction that I'm missing?


--8<---------------cut here---------------start------------->8---
#!/usr/bin/env python

class Foo(object):

def __init__(self):
def func(*args):
return str(args)
self.a=func

def b(*args):
return str(args)

@classmethod
def c(*args):
return str(args)

f=Foo()
print f.a(1) # just a callble
print f.b(1) # an instance method
print f.c(1) # a class method
--8<---------------cut here---------------end--------------->8---

Florian
--
<http://www.florian-diesch.de/>
-----------------------------------------------------------------------
** Hi! I'm a signature virus! Copy me into your signature, please! **
-----------------------------------------------------------------------
Dec 11 '07 #26
MonkeeSage wrote:
what am I missing?
To my eyes, when you write:
>I think it muddies the water to say that a.a() and a.a are the same
thing--obviously they are not. In the common case, the first is a
method, and the second is a variable.
What you are most obviously missing is what's shown by

b=a.a
b()

IOW I am tempted to make the prediction that you never use bound methods as
values :)

Cheers, BB

Dec 19 '07 #27

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

1 post views Thread by Alexander Kervero | last post: by
5 posts views Thread by Steve - DND | last post: by
8 posts views Thread by Thomas Girod | last post: by
3 posts views Thread by vivekian | last post: by
3 posts views Thread by redefined.horizons | last post: by
2 posts views Thread by prabhupr | last post: by
reply views Thread by rosydwin | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.