Distinguishing attributes and methods

T

tjhnson

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

Marc 'BlackJack' Rintsch

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
 
M

MonkeeSage

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
 
J

James Stroud

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.

Sure. Import types and test, then color code based on the test result.

For example:

py> import types
py> def doit(stuff):
.... print stuff
....
py> class Thing(object):
.... def amethod(self):
.... print 42
....
py> t = Thing()
py> type(t.amethod) is types.MethodType
True
py> type(t.doit) is types.FunctionType
True
py> type(Thing.amethod) is types.UnboundMethodType
True
py> t.value = 4
py> type(t.value) not in (types.FunctionType, types.UnboundMethodType,
types.MethodType)
True


James

--
James Stroud
UCLA-DOE Institute for Genomics and Proteomics
Box 951570
Los Angeles, CA 90095

http://www.jamesstroud.com
 
M

Marc 'BlackJack' Rintsch

I think he means callable attributes (methods) and non-callable
attributes (variables).

But not every callable attribute is a method.

Ciao,
Marc 'BlackJack' Rintsch
 
M

MonkeeSage

But not every callable attribute is a method.

Ciao,
Marc 'BlackJack' Rintsch

I swear, you dynamic programmers and your metaprogramming
tomfoolery! :p

Regards,
Jordan
 
B

Bruno Desthuilliers

(e-mail address removed) a écrit :
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.
Documentation.

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.

Actually, in Python, what you call "methods" are technically attributes
- usually class attributes, instances of the function class - until they
are looked up, at which time the lookup mechanism detect that they
implement the descriptor protocol, invoke it, an return the result of
this invocation - here a 'method' instance - in place of the original
attribute.
Tips? Ideas? Best practices?

Reading the doc ?-)

Else, you can check whether the attribute is an instance of
types.MethodType - but that's not 100% garanteed to work (someone could
implement it's own descriptor type acting like a function but not
returning a method object).

Or if all you need to know is if the attribute is callable, then just ask:

print callable(obj.attr)

My 2 cents
 
B

Bruno Desthuilliers

MonkeeSage a écrit :
I think he means callable attributes (methods) and non-callable
attributes (variables).

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

MonkeeSage

MonkeeSage a écrit :





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
 
M

Marc 'BlackJack' Rintsch

On Dec 8, 12:56 pm, Bruno Desthuilliers

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
 
R

Roberto Bonvallet

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 :)
 
G

Glenn Hutchings

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)
 
M

MonkeeSage

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
 
B

Bruno Desthuilliers

MonkeeSage a écrit :
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.
 
B

Bruno Desthuilliers

MonkeeSage a écrit :
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...
 
R

Roy Smith

Bruno Desthuilliers said:
MonkeeSage a écrit :

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

Bruno Desthuilliers

Roy Smith a écrit :
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.
 
M

MonkeeSage

MonkeeSage a écrit :





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.


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_(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. 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
 
J

Jan Claeys

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
 
M

Marc 'BlackJack' Rintsch

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,902
Latest member
Elena68X5

Latest Threads

Top