What is class method?

H

Hussein B

Hi,
I'm familiar with static method concept, but what is the class method?
how it does differ from static method? when to use it?
--
class M:
def method(cls, x):
pass

method = classmethod(method)
 
M

MeTheGameMakingGuy

Hi,
I'm familiar with static method concept, but what is the class method?
how it does differ from static method? when to use it?
--
class M:
 def method(cls, x):
    pass

 method = classmethod(method)

Firstly, don't use method = classmethod(method). Decorators are far
better. The following code has the same effect:

class M:
@classmethod
def method(cls, x):
pass

Far more readable, right?

Class methods are useful if you've got lots of inheritance happening.
The first argument passed in is the class calling the method. Handy
for a mix-in: it can add methods affecting the actual class it's mixed
into, rather than messing with the mix-in itself.
 
H

Hrvoje Niksic

Hussein B said:
Hi,
I'm familiar with static method concept, but what is the class method?
how it does differ from static method? when to use it?
--
class M:
def method(cls, x):
pass

method = classmethod(method)

Use it when your method needs to know what class it is called from.
This makes sense in the context of subclassing:

class M(object):
@classmethod
def method(cls, x):
print cls, x

class N(M):
pass
<class '__main__.N'> 1
 
C

castironpi

Firstly, don't use method = classmethod(method). Decorators are far
better. The following code has the same effect:

class M:
 @classmethod
 def method(cls, x):
  pass

Far more readable, right?

Class methods are useful if you've got lots of inheritance happening.
The first argument passed in is the class calling the method. Handy
for a mix-in: it can add methods affecting the actual class it's mixed
into, rather than messing with the mix-in itself.

It is similar to:

class M: #not correct as shown
def newmaker( self, x ):
newinst= self.__class__( arg1, arg2, x )
return newinst

m1= M()
m2= m1.newmaker( 'abc' )

except you don't need the first instance to do it with. Notice you
get a new instance of whatever class m1 is an instance of, rather than
necessarily M.

class N( M ):
pass

m1= N()
m2= m1.newmaker( 'abc' )

m2 is of class N now too.
 
M

Maric Michaud

Le Sunday 24 August 2008 10:32:34 Hussein B, vous avez écrit :
Hi,
I'm familiar with static method concept, but what is the class method?
how it does differ from static method? when to use it?
--
class M:
def method(cls, x):
pass

method = classmethod(method)

As it has been said, it adds polymorphic behavior to static method concept by
the mean of a reference to the real class that called it.
.....: @classmethod
.....: def factory(cls, *args) : return cls(*args)
.....:
.....:
.....: def __init__(self, a, b) :
.....: print a, b
.....:
.....:
[161]: A.factory()
...[161]: said:
[162]: B.factory(1, 2)
1 2
...[162]: <__main__.B object at 0x2b88d0e33bd0>



It is a common advice that staticmethod should not exist in python, as they do
nothing compared to module level functions, and we should always use
classmethods in place of them.
 
M

Medardo Rodriguez (Merchise Group)

I'm familiar with static method concept, but what is the class method?
how it does differ from static method? when to use it?

"Class Methods" are related to the meta-class concept introduced since
the first beginning of OOP but not known enough so far.
If you are capable to reason (to model) using that concept, the you
will need "classmethod" decorator in Python.

"Static Methods" are global operations but are declared in the
name-space context of a class; so, they are not strictly methods.

In Python everything is an object, but functions declared in the
module scope not receive the instance of the module, so they are not
module methods, they are not methods, they are global functions that
are in the name-space context of the module in this case.

Methods always receive the instance as a special argument (usually
declared as self in Python). Classes (theoretically speaking) are also
objects (dual behavior).

Let's be explicit:

#<code>
class Test(object):
def NormalMethod(self):
print 'Normal:', self

@staticmethod
def StaticMethod(self=None):
print 'Static:', self

@classmethod
def ClassMethod(self):
print 'Class:', self

test = Test()
test.NormalMethod()
test.StaticMethod()
test.ClassMethod() # the instance "test" is coerced to it's class to
call the method.
#</code>

Regards
 
S

Steven D'Aprano

Use it when your method needs to know what class it is called from.


Ordinary methods know what class they are called from, because instances
know what class they belong to:

def method(self, *args):
print self.__class__

You use class methods when you DON'T need or want to know what instance
it is being called from, but you DO need to know what class it is called
from:

@classmethod
def cmethod(cls, *args):
print cls


Why is this useful? Consider the dict method "fromkeys". You can call it
from any dictionary, but it doesn't care which dict you call it from,
only that it is being called from a dict:
{}.fromkeys([1, 2, 3]) {1: None, 2: None, 3: None}
{'monkey': 42}.fromkeys([1, 2, 3])
{1: None, 2: None, 3: None}


Any method that behaves like dict.fromkeys() is an excellent candidate
for classmethod.
 
H

Hrvoje Niksic

Steven D'Aprano said:
Use [classmethod] when your method needs to know what class it is
called from.

Ordinary methods know what class they are called from

I guess I should have added "and no more". :)
Why is this useful? Consider the dict method "fromkeys". You can
call it from any dictionary, but it doesn't care which dict you call
it from, only that it is being called from a dict:

That's also a good example of the difference between classmethod and
staticmethod, since fromkeys is smart enough to use the type
information.
.... pass
....<class '__main__.X'> # not <type 'dict'>

If 'fromkeys' were a staticmethod, it would have to be hardcoded to
always create dicts.
 
B

Bruno Desthuilliers

MeTheGameMakingGuy a écrit :
Firstly, don't use method = classmethod(method). Decorators are far
better. The following code has the same effect:

class M:
@classmethod
def method(cls, x):
pass

Far more readable, right?

Yes, but will only work with Python >= 2.4. There are cases where you
want to keep compatibility with Python 2.3...
Class methods are useful if you've got lots of inheritance happening.
The first argument passed in is the class calling the method. Handy
for a mix-in: it can add methods affecting the actual class it's mixed
into, rather than messing with the mix-in itself.

I'm not sure I get your point here.

As far as I'm concerned, classmethods are useful anywhere you need to
work on the class object itself.
 
B

Bruno Desthuilliers

Maric Michaud a écrit :
(snip)
>
It is a common advice that staticmethod should not exist in python, as they do
nothing compared to module level functions,

They "do" nothing more, but are accessible thru a class object instead
of being accessible thru a module object. It sometimes happens to be
useful (for a very very low value of 'sometimes' as far as I'm
concerned, but still...)
 
B

Bruno Desthuilliers

Medardo Rodriguez (Merchise Group) a écrit :
"Class Methods" are related to the meta-class concept introduced since
the first beginning of OOP but not known enough so far.
If you are capable to reason (to model) using that concept, the you
will need "classmethod" decorator in Python.

In Python, there's *no* relationship between classmethods and
metaclasses. A classmethod is just a descriptor class attribute that act
as a wrapper around a function in such a way that when the attribute is
looked up (weither on the class or an instance of it) yields another
(callable) wrapper around the function and the class, this last wrapper
being responsible for calling the function with the class itself as
first argument.
"Static Methods" are global operations but are declared in the
name-space context of a class; so, they are not strictly methods.

In Python everything is an object, but functions declared in the
module scope not receive the instance of the module, so they are not
module methods, they are not methods, they are global functions

You can drop the 'global' - there's nothing like a real global scope in
Python.
that
are in the name-space context of the module in this case.

Methods always receive the instance as a special argument (usually
declared as self in Python).

Nope. Functions wrapped by a method object receive the instance as
*first* (not 'special') argument. In Python, a method is only a wrapper
object around the function, the class and the instance. This wrapper is
built by the function object's __get__ method (descriptor protocol) each
time the attribute is looked up.
Classes (theoretically speaking) are also
objects

Why "theoretically speaking" ?

Python's classes *are* objects.

(dual behavior).

Let's be explicit:

#<code>
class Test(object):
def NormalMethod(self):
print 'Normal:', self

<ot>
pep08 : method names should be all_lower
@staticmethod
def StaticMethod(self=None):
print 'Static:', self

@classmethod
def ClassMethod(self):
print 'Class:', self

<ot>
The convention for classmethod is to name the first function argument 'cls'.
test = Test()
test.NormalMethod()
test.StaticMethod()
test.ClassMethod() # the instance "test" is coerced to it's class to
call the method.

Nope. There's nothing like "coercion" in Python. It's just that the
descriptor protocol pass both the instance and it's class (or only the
class if the lookup happens on the class itself) to the __get__ method,
so the classmethod's __get__ method can store a reference to it and use
that reference as first arg when calling the wrapped function.

If you really intend to go into low-level explanations of Python's
object model, please get your facts right first. It's already difficult
enough to explain, no need to add misleading or inexact stuff.
 
B

Bruno Desthuilliers

Hussein B a écrit :
Hi,
I'm familiar with static method concept,

Which is more often than not useless in Python - we have true functions
and modules.
but what is the class method?

Short answer : It's a method that can be looked up upon both the class
or an instance of it, and takes the class itself (instead of the
instance) as first parameter.
how it does differ from static method?

static methods don't receive the class object as first param.
when to use it?

When you need to access the class (using polymorphic dispatch), don't
care about the instance itself, and want to be able to call the method
on both the class or an instance.
 
M

Medardo Rodriguez (Merchise Group)

In Python, there's *no* relationship between classmethods and metaclasses.

In OOP the concept of meta-class has everything to do with class
methods, regardless if is in Python, SmallTalk or CLOSS. "classmethod"
decorator it's just a syntax sugar structure to define them. There is
no difference (conceptually) on "method1" and "method2":
<sample>
class MetaXClass(type):
def Method1(self): pass
class Xclass(object):
__metaclass__ = MetaXClass
@classmethod
def Method2(self): pass
You can drop the 'global' - there's nothing like a real global scope in
Python.


Yes, they are. Functions defined at module level or using staticmethod
decorator don't receive the instance as argument, they are globa,
You can study in Python:
* global keyword
* globals function
Nope. Functions wrapped by a method object receive the instance as *first*
(not 'special') argument. In Python, a method is only a wrapper object
around the function, the class and the instance. This wrapper is built by
the function object's __get__ method (descriptor protocol) each time the
attribute is looked up.

Seriously, I'm a programmer, not a intermediate code engineer. I know
very well how python work in its inner, but this forum is to talk
about Python programming.
Nevertheless, in some level is always call the original defined
function, that YES, it receives the self as an argument.
Why "theoretically speaking" ?

Why not?

That's only means that python is nice because fulfills very well the
best OOP theory.
<ot>
pep08 : method names should be all_lower
</ot>

Not for me. I use to be consistent in being pythonic, but there are
some few exceptions.
<ot>
The convention for classmethod is to name the first function argument 'cls'.
</ot>

I just wanted the guy who made the question, don't see other
differences but classmethod decorator.
Sorry!
Nope. There's nothing like "coercion" in Python.
http://docs.python.org/ref/coercion-rules.html

If you really intend to go into low-level explanations of Python's object


I NEVER pretended to do that. Programming I like is high level,
because of that Python is right now my preferred language,
nevertheless I know every thing I'm interested in inner Python.

My best regards
 
R

Raymond Hettinger

Hi,
I'm familiar with static method concept, but what is the class method?
how it does differ from static method? when to use it?

I use them when I need alternative constructors for a class.

class Angle(object):

def __init__(self, degrees):
self.degrees = degrees

@classmethod
def from_radians(cls, radians):
return cls(radians / pi * 180.0)

This lets me construct a new angle with either Angle(45) or
Angle.from_radians(pi/4).

The example shows what is special about classmethods. The first
argument is a class, not an instance.


Raymond
 
M

Matthew Fitzgibbons

Medardo said:
In OOP the concept of meta-class has everything to do with class
methods, regardless if is in Python, SmallTalk or CLOSS. "classmethod"
decorator it's just a syntax sugar structure to define them. There is
no difference (conceptually) on "method1" and "method2":
<sample>
class MetaXClass(type):
def Method1(self): pass
class Xclass(object):
__metaclass__ = MetaXClass
@classmethod
def Method2(self): pass
</sample>

Not quite:
.... def method1(self): pass
........ __metaclass__ = MetaXClass
.... @classmethod
.... def method2(self): pass
....Traceback (most recent call last):

-Matt
 
B

Bruno Desthuilliers

Medardo Rodriguez (Merchise Group) a écrit :
In OOP the concept of meta-class has everything to do with class
methods, regardless if is in Python, SmallTalk or CLOSS.

Ok, I guess we're not going to agree here, since you take for granted
that there's such a thing as a universal, language-independant
definition of OOP concepts, and I don't (except for the two very basic
concepts : 1/ an object is defined by an identity, a state and a
behaviour, 2/ objects interact by sending messages to each others).
"classmethod"
decorator it's just a syntax sugar structure to define them. There is
no difference (conceptually) on "method1" and "method2":
<sample>
class MetaXClass(type):
def Method1(self): pass
class Xclass(object):
__metaclass__ = MetaXClass
@classmethod
def Method2(self): pass
</sample>

There's two obvious differences : Method1 is an instance method of class
MetaXClass, and can only be called on instances of MetaXClass, while
Method2 is a class method of class Xclass and can be called on either
Xclass or instances of Xclass.

Yes, they are. Functions defined at module level or using staticmethod
decorator don't receive the instance as argument,

Nested functions don't receive "the" instance as argument neither...
they are globa,

staticmethods are not, even from a Python-specific POV.
You can study in Python:
* global keyword
* globals function

I don't think I need to study them, thanks.

But I must admit that since I disagree with you on the basis of "generic
CS concept vs Python specific concept", I shouldn't have mentionned this
- from a Python specific POV, functions defined at the top-level of a
module are indeed "globals" (just like any name bound at the module
level). OTHO, you too are now relying on the python-specific definition
of "global" here.
Seriously, I'm a programmer, not a intermediate code engineer. I know
very well how python work in its inner, but this forum is to talk
about Python programming.
Indeed.

Nevertheless, in some level is always call the original defined
function, that YES, it receives the self as an argument.

Sorry, I don't understand the above sentence (seriously - no nitpicking
here).

Hmmm.... Because in Python, classes *are* objects, and not only from a
theoretical POV ?-)
That's only means that python is nice because fulfills very well the
best OOP theory.

Which one ? Java's OOP theory ? Smalltalk's OOP theory ? CLOS OOP
theory? Javascript's OOP theory ? Io's OOP theory ? Eiffel's OOP theory?

As far as I'm concerned, there are as many "OOP theories" as they are
"OOP languages".
Not for me. I use to be consistent in being pythonic, but there are
some few exceptions.

<ot>
Coming from the Windows world ?
I just wanted the guy who made the question, don't see other
differences but classmethod decorator.
Sorry!


http://docs.python.org/ref/coercion-rules.html

Ok, you got me on this one. What I meant was that there was nothing
like typecasting. *And* the way the class is passed to classmethods
called on an instance has nothing to do with coercion anyway (at least
for commonly accepted definitions of 'coercion').
I NEVER pretended to do that.

Sorry for this last paragraph anyway. I often tend to get too harsh, and
regret it later. Sincerely.


Best regards, and thanks for not being as ill-tempered as I tend to.
 

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,780
Messages
2,569,608
Members
45,244
Latest member
cryptotaxsoftware12

Latest Threads

Top