Class Methods Vs Any Other Callable

V

vbgunz

I remember learning closures in Python and thought it was the dumbest
idea ever. Why use a closure when Python is fully object oriented? I
didn't grasp the power/reason for them until I started learning
JavaScript and then BAM, I understood them.

Just a little while ago, I had a fear of decorators because I really
couldn't find a definitive source to learn them (how to with with @).
How important are they? They must be important otherwise why have'em
in the language? I had to learn'em and then suddenly, BAM. I
understand them.

My main issue with closures and decorators was hidden in the fact of
how *dead simple* they were. All I needed were reasons to use them
over doing it X style. So what is my point? How dead simple are class
methods? I must be missing there point so I am convinced they must be
dead simple.

classes, functions, instance and static methods are easy. So easy in
fact, I could shoot myself in the foots without looking (preferably
without aiming). So, why am I stuck on the *idea* of a class method?

An instance method works on the instance
A Static method is basically a function nested within a class object
A class method is overkill?

I can call a static or class method through either the class OR any
instance of it. I've never designed a method that took advantage of
the class name except in cases where I needed to extend a super class
*but* even in this case, I didn't use the enclosing class name...

Whats the deal with class methods, why use them over anything else?
What does a class method accomplish in at least one line shorter than
anything else? Does it help reduce duplication or typing? I am at a
lost for words that can shed at least *one* good reason to use them.

What is the one greatest reason to use them? A little syntax and
explanation can go a long long way. I am failing to understand them so
any help is really appreciated here!
 
D

Diez B. Roggisch

An instance method works on the instance
A Static method is basically a function nested within a class object
A class method is overkill?

If anything, a static method is overkill. See it this way: *if* you for some
reason put a method into an enclosing context - isn't it worth having a
reference to that?
I can call a static or class method through either the class OR any
instance of it. I've never designed a method that took advantage of
the class name except in cases where I needed to extend a super class
*but* even in this case, I didn't use the enclosing class name...

Whats the deal with class methods, why use them over anything else?
What does a class method accomplish in at least one line shorter than
anything else? Does it help reduce duplication or typing? I am at a
lost for words that can shed at least *one* good reason to use them.

What is the one greatest reason to use them? A little syntax and
explanation can go a long long way. I am failing to understand them so
any help is really appreciated here!

There is not one greatest reason. They have their uses as e.g.
factory-methods for instances of the class. Or as e.g. registering
functions for notifications amongst instances of the class. In which case
writing

class Foo:

@classmethod
def register(cls, listener):
cls.LISTENERS.append(listener)

is much more robust because you could rename Foo the way you like - register
won't be affected.

Diez
 
G

George Sakkis

If anything, a static method is overkill. See it this way: *if* you for some
reason put a method into an enclosing context - isn't it worth having a
reference to that?

My feeling exactly; these days I almost always use class methods
instead of static. I vaguely remember seeing somewhere an example
where a static method was the only (elegant) solution; neither a class
method nor a plain function would do. I'll post it if I find it unless
someone beats me to it.

George
 
V

vbgunz

An instance method works on the instance
If anything, a static method is overkill...
class Foo:

   @classmethod
   def register(cls, listener):
       cls.LISTENERS.append(listener)

When I learned about static methods, I learned they're a way to
tightly couple some functionality with a class without tying the
functionality to any of the instances. I see them as nothing more than
a design decision. To me they make some sense.

Other than a methods signature (classmethod(cls, l) and a
staticmethod(l)) a class method does anything that a static method
does and gets the CLS reference for FREE? Is this why a static method
is considered to be overkill? In other words, either one can be called
from either the class or the instance and both work pretty much the
same *but* only the class method includes the class for reference and
the static method does not?

The only real difference I see between an instance and either a class
or static method is the whole bound/unbound thing. Otherwise, even an
instance can do what the others do *just* the instance method can only
make those calls through an instance and not the class.

Instance methods make the most sense. A static method makes sense too
*but* I can see how a class method not only does what a static method
does but how a class method *also* gets the cls reference for free.

Am I correct?
 
D

Diez B. Roggisch

When I learned about static methods, I learned they're a way to
tightly couple some functionality with a class without tying the
functionality to any of the instances. I see them as nothing more than
a design decision. To me they make some sense.

Which you can say exactly about classmethods - because there is *no*
instance.
Other than a methods signature (classmethod(cls, l) and a
staticmethod(l)) a class method does anything that a static method
does and gets the CLS reference for FREE?
Yes.

Is this why a static method
is considered to be overkill? In other words, either one can be called
from either the class or the instance and both work pretty much the
same *but* only the class method includes the class for reference and
the static method does not?

Yes.
The only real difference I see between an instance and either a class
or static method is the whole bound/unbound thing. Otherwise, even an
instance can do what the others do *just* the instance method can only
make those calls through an instance and not the class.

Which is a pretty heavy distinction.
Instance methods make the most sense. A static method makes sense too
*but* I can see how a class method not only does what a static method
does but how a class method *also* gets the cls reference for free.

I don't understand the last part - but I certainly agree on the "instance
methods make the most sense". But *if* you want a hierarchy
of "sensefulness",

method > classmethod > staticmethod

is the ordering to apply I'd say. Again: classmethods get *more* context
than staticmethods *without* needing an instance. More is better :)

Diez
 
V

vbgunz

Instance methods make the most sense. A static method makes sense too
I don't understand the last part - but I certainly agree on the "instance
methods make the most sense". But *if* you want a hierarchy
of "sensefulness",

method > classmethod > staticmethod

OK, I am sold. If in case I find myself needing a static-method, I'll
simply make it a class-method instead. One thing that stuck out from
earlier and I'll compare it to linking is the "relative" usefulness of
cls. There are 2 conditions I can immediately come up with. 1, rename
the class and the class method still works. 2, move the method from
working on one particular class and it'll most likely work unchanged
(w/ the same interface) in another.

Other than the 2 reasons above (2 making more sense), what is a really
good reason to pull out the class method. In other words, when you see
one, what is the first thing that comes to mind? When you write one,
what was the first thing on your mind? Other than "similar to static-
methods", at what point will you be glad you used one? To sum it up,
what is the best role for a class-method that does not turn your work
into code-soup?
 
V

vbgunz

Instance methods make the most sense. A static method makes sense too
Sorry I quoted this earlier and meant to respond to it. What I meant
was, might as well use a class method over a static method AND in
doing so, cls is free. I sort of repeated the same thing over and
over. I think my main concern was trying to make sure I could grasp at
least that much.
 
A

Arnaud Delobelle

George Sakkis said:
My feeling exactly; these days I almost always use class methods
instead of static. I vaguely remember seeing somewhere an example
where a static method was the only (elegant) solution; neither a class
method nor a plain function would do. I'll post it if I find it unless
someone beats me to it.

George

__new__ is a static method!
 
B

bruno.desthuilliers

__new__ is a static method!

__new__ is a special-cased staticmethod that 1/ must not be declared
as such and 2/ takes the class object as first args. As far as I'm
concerned, it's semantically a classmethod.
 
B

bruno.desthuilliers

My feeling exactly; these days I almost always use class methods
instead of static. I vaguely remember seeing somewhere an example
where a static method was the only (elegant) solution; neither a class
method nor a plain function would do. I'll post it if I find it unless
someone beats me to it.

No concrete example here but I surely remember having used
staticmethods in one case where I needed class-based polymorphic
dispatch and eventually implementation inheritance (to get a default
implementation) for something that didn't required access to the
class object.
 
C

Carl Banks

Other than the 2 reasons above (2 making more sense), what is a really
good reason to pull out the class method. In other words, when you see
one, what is the first thing that comes to mind? When you write one,
what was the first thing on your mind? Other than "similar to static-
methods", at what point will you be glad you used one? To sum it up,
what is the best role for a class-method that does not turn your work
into code-soup?


When classmethods are inherited, they are called with the class it was
invoked with, rather than the class they were defined in. Try this
example:


class A(object):
@classmethod
def classname(cls):
print cls.__name__

@staticmethod
def staticname():
print "A"

class B(A):
pass

B.staticname()
B.classname()


Carl Banks
 
B

bruno.desthuilliers

It's a static method!

Sorry Arnaud, I probably didn't made it clear enough : I do know it is
a staticmethod object. What I say is that
1/ it's special-cased since you don't *explicitely* declare it as a
staticmethod
2/ it behaves just like a classmethod, since it takes the class as
first argument.

IOW, I'm talking about semantic, not implementation.
 
I

Ivan Illarionov

[...]
when you see
one, what is the first thing that comes to mind? When you write one,
what was the first thing on your mind? Other than "similar to static-
methods", at what point will you be glad you used one? To sum it up,
what is the best role for a class-method that does not turn your work
into code-soup?

The first thing on my mind when I see a classmethod is that I may need a
metaclass here.

class A(object):
@classmethod
def do_something_with_aclass(cls):
pass

@classmethod
def do_something_diffferent_with_aclass(cls):
pass

def do_something(self):
pass

is similar to:

class M(type):
def do_something_with_aclass(cls):
pass

def do_something_diffferent_with_aclass(cls):
pass

class A:
__metaclass__ = M

def do_something(self):
pass

-- Ivan
 
A

Arnaud Delobelle

Sorry Arnaud, I probably didn't made it clear enough : I do know it is
a staticmethod object. What I say is that
1/ it's special-cased since you don't *explicitely* declare it as a
staticmethod
2/ it behaves just like a classmethod, since it takes the class as
first argument.

IOW, I'm talking about semantic, not implementation.

.... and I was being facetious, not serious :)
 
G

George Sakkis

No concrete example here but I surely remember having used
staticmethods in one case where I needed class-based polymorphic
dispatch and eventually implementation inheritance (to get a default
implementation)  for something that didn't required access to the
class object.

Yes, that's common, but a class method could be used just as well
here. I couldn't find the original example but IIRC it was related to
monkeypatching. Say that you have a package P1 that has some useful
classes:

class A(object): pass
class B(A): pass
class C(A): pass

You also have an unrelated package P2 with some useful functions:

def f1(): return 0
def f2(): return 1

Naturally you want to combine these two. One common pattern when doing
so turns out to be like:

# e.g. x = random.choice([A(), B(), C()])
...
assert isinstance(x, A)
if type(x) in (A,B):
print f1()
elif type(x) is C:
print f2()

With a less trivial hierarchy and number of functions, it becomes
clear that it would help a lot if you could refactor it somehow so you
can just say "print x.f()" and it would do the right thing.
Monkeypatching it as a normal method ("A.f = f1; C.f = f2") doesn't
work because it expects self as the first argument, and similarly for
class methods and the cls argument. OTOH static methods do the trick:

A.f = staticmethod(f1)
C.f = staticmethod(f2)
print x.f()

Admittedly it's not a common scenario but it's good to know it's there
if you need it.

George
 
B

Bruno Desthuilliers

vbgunz a écrit :
I remember learning closures in Python and thought it was the dumbest
idea ever. Why use a closure when Python is fully object oriented? I
didn't grasp the power/reason for them until I started learning
JavaScript and then BAM, I understood them.

Just a little while ago, I had a fear of decorators because I really
couldn't find a definitive source to learn them (how to with with @).
How important are they? They must be important otherwise why have'em
in the language? I had to learn'em and then suddenly, BAM. I
understand them.

My main issue with closures and decorators was hidden in the fact of
how *dead simple* they were. All I needed were reasons to use them
over doing it X style. So what is my point? How dead simple are class
methods?

Way dumber than closures and HOFs (which is what 'decorators' are when
you take back the @syntactic sugar).

A classmethod is simply a method that works on the class itself - it
takes the class as first argument, instead of taking the instance.
I must be missing there point so I am convinced they must be
dead simple.

classes, functions, instance and static methods are easy. So easy in
fact, I could shoot myself in the foots without looking (preferably
without aiming). So, why am I stuck on the *idea* of a class method?

Could it be because you don't see the implication of classes being
objects too ?
An instance method works on the instance
A Static method is basically a function nested within a class object
A class method is overkill?

Nope. It's sometimes pretty usefull.
I can call a static or class method through either the class OR any
instance of it. I've never designed a method that took advantage of
the class name except in cases where I needed to extend a super class
*but* even in this case, I didn't use the enclosing class name...

s/name//g

What you have is the class *object*, not the class name.
Whats the deal with class methods, why use them over anything else?
What does a class method accomplish in at least one line shorter than
anything else? Does it help reduce duplication or typing? I am at a
lost for words that can shed at least *one* good reason to use them.
> What is the one greatest reason to use them?

Factory methods (alternate constructors...) is probably the most obvious
use case. You need to get at the class to instanciate it, don't you ? An
example of this pattern is dict.fromkeys().

You'll find a more elaborate example here too:
http://groups.google.fr/group/comp....e8a12bcf375/a31bb0e13bf09316#a31bb0e13bf09316

HTH
 
B

Bruno Desthuilliers

vbgunz a écrit :
Sorry I quoted this earlier and meant to respond to it. What I meant
was, might as well use a class method over a static method AND in
doing so, cls is free.

cf Georges Sakkis point about this. 'cls is free' ? Well, not
necessarily. Your function must take the class as first argument, and so
you just can't use just any plain function as a classmethod.
 
A

Arnaud Delobelle

OK then let me reply pedantically:
Sorry Arnaud, I probably didn't made it clear enough : I do know it is
a staticmethod object. What I say is that
1/ it's special-cased since you don't *explicitely* declare it as a
staticmethod

In some cases you have to:

class Foo(object): pass

# Later on I want to redefine Foo.__new__

@staticmethod
def Foo__new__(cls):
print "new Foo!"
return object.__new__(cls)

Foo.__new__ = Foo__new__
2/ it behaves just like a classmethod, since it takes the class as
first argument.

When you invoke it implicitely maybe, but not when you do so
explicitely! Look at my example below: to create my Foo object, I
have to write

object.__new__(Foo)
IOW, I'm talking about semantic, not implementation.

I understand what you mean, and from that point of view you can argue
against my example above (after all, my example is code, not pure
concept) but for me it is simpler to think of __new__ as a
staticmethod (which it is!), plain and simple.
 
B

Bruno Desthuilliers

Arnaud Delobelle a écrit :
OK then let me reply pedantically:


In some cases you have to:

class Foo(object): pass

# Later on I want to redefine Foo.__new__

@staticmethod
def Foo__new__(cls):
print "new Foo!"
return object.__new__(cls)

Foo.__new__ = Foo__new__

Point taken. But you'll admit that monkeypatching the __new__ method is
somewhat uncommon !-)

<nb>
Poor word choice here I'm afraid - of course a staticmethod doesn't
"behave" like a classmethod object. But you of course __knew__ what I
meant !-)
When you invoke it implicitely maybe, but not when you do so
explicitely!

I'm not talking about how you invoke it (FWIW, direct invocation of
__new__ is pretty rare, parent call excepted - and then, well, it mostly
mirrors a direct parent call within an overridden instance method). It's
about having __new__ taking the class as first argument.

FWIW, I wonder why the BDFL choosed to implement __new__ as a
staticmethod - there are probably some pretty good reasons, but not
knowing them, it looks like __new__ would have been a perfect candidate
for a classmethod.

So far, the only reason I can think of is that making it a classmethod
would have required the use of super(Parent, cls) to call the parent's
class __new__, which may (or may not - never had the case) be
problematic (any guru on this ?)
I understand what you mean, and from that point of view you can argue
against my example above

It's somehow difficult to argue against something that's just the plain
and naked truth. My one and only argument is about __new__ being
semantically close enough to a classmethod to wonder why it isn't one.
(after all, my example is code, not pure
concept) but for me it is simpler to think of __new__ as a
staticmethod (which it is!), plain and simple.

I could by no mean hold it against you !-)
 

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

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top