Steven Bethard wrote:
John M. Gabriele wrote:
1. Are all of my class's methods supposed to take 'self' as their
first arg?
If by "class's methods" you mean methods on which you called
classmethod, then no, they shouldn't take a 'self' parameter, they
should take a 'cls' parameter because the first argument to the function
will be the class:
class C(object):
@classmethod
def f(cls, *args):
# do stuff
Sorry -- I'm not as far along as you suspect. :) I've
never yet seen this "@classmethod" syntax. I'm supposing that
it's part of this so-called "new-style" class syntax.
When I ask "are all my class's methods...", I mean, when
I'm writing a class statement and the def's therein -- are
all those def's supposed to take 'self' as their first arg.
From your reply, I gather that, unless I'm using this special
syntax (@classmethod or @staticmethod), all my def's are supposed
to take 'self' as their first arg.
Undecorated methods (e.g. those that are not wrapped with classmethod or
staticmethod) should, on the other hand, take a 'self' parameter.
Ok. Check.
So then, are all def's -- that take 'self' as their first --
argument -- in a class statement, instance methods?
2. Am I then supposed to call them with MyClass.foo() or instead:
bar = MyClass()
bar.foo()
Classmethods should be called from the class. Python allows you to call
them from the instance, but this almost never does what you want, e.g.:
py> d = {}
py> d.fromkeys(range(4))
{0: None, 1: None, 2: None, 3: None}
py> d
{}
Note that 'd' is not updated -- I called a classmethod, not an
instancemethod. If I had called dict.fromkeys instead, this would have
been clearer.
Right. An important lesson in C++ as well.
3. Is "bound method" a synonym for instance method?
4. Is "unbound method" a synonym for class method?
No. To simplify things a little[1], a "bound method" is an instance
method that has been associated with a specific instance, and an
"unbound method" is an instance method that has not been associated with
a specific instance.
Ok! Now I'm making some headway. *This* is getting
at the crux of the biscuit.
Consider the difference between str.join and ''.join:
py> str.join
<method 'join' of 'str' objects>
>
py> ', '.join
<built-in method join of str object at 0x01233620>
>
Hmm... weird.
py> str.join(['a', 'b', 'c'])
Traceback (most recent call last):
File "<interactive input>", line 1, in ?
TypeError: descriptor 'join' requires a 'str' object but received a 'list'
>
Right -- 'cause there's no actual instance of a string
to do the joining. Check.
py> ', '.join(['a', 'b', 'c'])
'a, b, c'
Check.
py> str.join(', ', ['a', 'b', 'c'])
'a, b, c'
Ack! Now you're creeping me out. Looking at the doc for str.join:
| py> help( str.join )
| Help on method_descriptor:
|
| join(...)
| S.join(sequence) -> string
|
| Return a string which is the concatenation of the strings in the
| sequence. The separator between elements is S.
|
It says that you didn't call that method correctly. Yet
it works anyway!? What's happening here?
In the example above, you can see that str.join is an "unbound method"
-- when I try to call it without giving it an instance, it complains. On
the other hand, ', '.join is a "bound method" because it has been bound
to a specific instance of str (in this case, the instance ', '). When I
call it without an instance, it doesn't complain because it's already
been bound to an instance.
Ok. I see that distinction. Thanks.
Where do the so-called "static methods" fit into all this?
By the name of them, it sounds like the same thing as class
methods...
Staticmethods, like classmethods, are associated with the class object,
not the instance objects.
That makes sense.
The main difference is that when a
staticmethod is called, no additional arguments are supplied, while when
a classmethod is called, a first argument, the class, is inserted in the
argument list:
py> class C(object):
... @classmethod
... def f(*args):
... print args
... @staticmethod
... def g(*args):
... print args
...
py> C.f(1, 2, 3)
(<class '__main__.C'>, 1, 2, 3)
py> C.g(1, 2, 3)
(1, 2, 3)
STeVe
Thanks for that nice example. It looks like you're always
supposed to call both class and static methods via the class
name (rather than an instance name). I'll read up on what
this new @classmethod and @staticmethod syntax means.
[1] Technically, I think classmethods could also considered to be "bound
methods" because in this case, the method is associated with a specific
instance of 'type' (the class in which it resides) -- you can see this
in the first argument that is supplied to the argument list of a
classmethod.
--
--- remove zees if replying via email ---
--
http://mail.python.org/mailman/listinfo/python-list