Sign up ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free.

There has been a discussion in chat relating to a question (the question itself being irrelevant to this one), that has revealed I may not know Python whatsoever.

In my mind, although terminology differs across languages, we may generally categorise functions as:

  • [free] functions
  • static methods / static member functions
  • non-static methods / non-static member functions

Apparently in Python there is another kind of function that doesn't fit into the above categories, one that is a method but "doesn't know its class".

What are "class methods" and "instance methods", in Python?

share|improve this question
1  
If anyone's interested in the chat discussion, start here: chat.stackexchange.com/transcript/message/26479002#26479002 – Yannis yesterday

TL;DR

  • an instance method knows its instance (and from that, its class)
  • a class method knows its class
  • a static method doesn't know its class or instance

Class methods

A class method is one that belongs to the class as a whole. It doesn't require an instance. Instead, the class will automatically be sent as the first argument. A class method is declared with the @classmethod decorator.

For example:

class Foo(object):
    @classmethod
    def hello(cls):
        print("hello from %s" % cls.__name__)
Foo.hello()
-> "Hello from Foo"
Foo().hello()
-> "Hello from Foo"

Instance Methods

On the other hand, an instance method requires an instance in order to call it, and requires no decorator. This is by far the most common type of method.

class Foo(object):
    def hello(self):
        print("hello from %s" % self.__class__.__name__)
Foo.hello()
-> TypeError: hello() missing 1 required positional argument: 'self'

(note: the above is with python3; with python2 you'll get a slightly different error)

Static methods

A static method is similar to a class method, but won't get the class object as an automatic parameter. It is created by using the @staticmethod decorator.

class Foo(object):
    @staticmethod
    def hello(cls):
        print("hello from %s" % cls.__name__)

Foo.hello()
-> TypeError: hello() missing 1 required positional argument: 'cls'

Documentation links

Here are links to the relevant python3 documentaton:

The data model documentation has this to say about the difference between class methods and static methods:

Static method objects Static method objects provide a way of defeating the transformation of function objects to method objects described above. A static method object is a wrapper around any other object, usually a user-defined method object. When a static method object is retrieved from a class or a class instance, the object actually returned is the wrapped object, which is not subject to any further transformation. Static method objects are not themselves callable, although the objects they wrap usually are. Static method objects are created by the built-in staticmethod() constructor.

Class method objects A class method object, like a static method object, is a wrapper around another object that alters the way in which that object is retrieved from classes and class instances. The behaviour of class method objects upon such retrieval is described above, under “User-defined methods”. Class method objects are created by the built-in classmethod() constructor.

Related questions

share|improve this answer
    
This is so strange to a non-Pythonista like me. Your static methods look strange! – Lightness Races in Orbit yesterday
4  
@LightnessRacesinOrbit: I don't think static methods are used particularly often in python. Using my system as an random sample, when I search through all of the packages I have installed, only about 1% of all methods are static methods (which frankly was more than I was expecting). – Bryan Oakley yesterday
1  
"Static methods" are usually a code smell, and are discouraged by e.g. Gogole Python style guide. – 9000 yesterday
3  
I think the answer would better if it drew attention to subclasses, which is where classmethods get some usefulness. – Winston Ewert yesterday
1  
@Kashyap: the TL;DR applies to the very first paragraph. I think it works better at the top than the bottom. – Bryan Oakley yesterday

What are “class methods” and “instance methods”, in Python?

Remember math class, "y is a function of x, f(x)?" Keep that in mind as you read the following descriptions:

Instance Methods

An instance method is function that is a function of an instance. It accepts the instance as an argument to it.

A built-in example of an instance method is str.lower:

>>> 'ABC'.lower()
'abc'

called on the instance of the string, it uses that information to return a new string.

Class Methods:

Remember, in Python, everything is an object. That means the class is an object, and can be passed as an argument to a function.

A class method is a function that is a function of the class. It accepts the class as an argument to it.

A builtin example is dict.fromkeys:

>>> dict.fromkeys('ABC')
{'C': None, 'B': None, 'A': None}

It implicitly knows its own class, and creates a new one of that class from the iterable. An OrderedDict demonstrates this when using the same method:

>>> from collections import OrderedDict
>>> OrderedDict.fromkeys('ABC')
OrderedDict([('A', None), ('B', None), ('C', None)])

Static Methods

You mention a method that "doesn't know its class" - this is a static method in Python. It is merely attached for convenience to the class object. It could optionally be a separate function in another module, but its call signature would be the same.

A static method is a function of neither the class nor the object.

A built-in example of a static method is str.maketrans from Python 3.

>>> str.maketrans('abc', 'bca')
{97: 98, 98: 99, 99: 97}

Given a couple of arguments, it makes a dictionary that is not a function of its class.

It is convenient because str is always available in the global namespace, so you can easily use it with the translate function:

>>> 'abracadabra'.translate(str.maketrans('abc', 'bca'))
'bcrbabdbcrb'

In Python 2, you have to access it from the string module:

>>> 'abracadabra'.translate(str.maketrans('abc', 'bca'))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: type object 'str' has no attribute 'maketrans'
>>> import string
>>> 'abracadabra'.translate(string.maketrans('abc', 'bca'))
'bcrbabdbcrb'

Example

class AClass(object):
    """In Python, a class may have several types of methods: 
    instance methods, class methods, and static methods
    """

    def an_instance_method(self, x, y, z=None):
        """this is a function of the instance of the object
        self is the object's instance
        """
        return self.a_class_method(x, y)

    @classmethod
    def a_class_method(cls, x, y, z=None):
        """this is a function of the class of the object
        cls is the object's class
        """
        return cls.a_static_method(x, y, z=z)

    @staticmethod
    def a_static_method(x, y, z=None):
        """this is neither a function of the instance or class to 
        which it is attached
        """
        return x, y, z

Let's instantiate:

>>> instance = AClass()

Now the instance can call all of the methods:

>>> instance.an_instance_method('x', 'y')
('x', 'y', None)
>>> instance.a_static_method('x', 'y')
('x', 'y', None)
>>> instance.a_class_method('x', 'y')
('x', 'y', None)

But the class is not usually intended to call the instance method, though it is expected to call the others:

>>> AClass.a_class_method('x', 'y')
('x', 'y', None)
>>> AClass.a_static_method('x', 'y')
('x', 'y', None)
>>> AClass.an_instance_method('x', 'y')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: an_instance_method() missing 1 required positional argument: 'y'

You would have to explicitly pass the instance to call the instance method:

>>> AClass.an_instance_method(instance, 'x', 'y')
('x', 'y', None)
share|improve this answer
    
"this is a static method in Python. It is merely attached for convenience to the class object. It could optionally be a separate function in another module, but its call signature would be the same." Seems more confusing than convenient. Why would you attach a function to a class if its body will have no notion of that class. – Lightness Races in Orbit yesterday
    
@LightnessRacesinOrbit I've elaborated on each point – Aaron Hall yesterday
    
Personally, the way I've always looked at it is that an instance method is an operation on a particular instance, a class method is a sort of constructor (for convenience, nothing like MyClass(1,2,3) but instead like, MyClass.get_special(1,2,3)), and a static method as just being a normal function that could stand alone anyway. – Zizouz212 yesterday
    
Yes, classmethods are typically used for alternative constructors (see my dict.fromkeys example above, see also the pandas.DataFrame source code), but that is not a defining characteristic. I sometimes merely need to access data stored at the class level from a method, without accessing the instance. If you're calling type(self) (or worse, self.__class__) and not otherwise using self directly in an instance method, that's a good sign that you should consider it to be a classmethod. As classmethods don't require instances, it makes them easier to unittest. – Aaron Hall yesterday
  • An "instance method" is a method that gets passed the instance object as its first parameter, which by convention is called self. This is the default.

  • A "static method" is a method without the initial self parameter. This is implemented with the @staticmethod decorator.

  • A "class method" is a method where the initial parameter is not an instance object, but the class object (see this part of the Python docs for what a "class object" is), which by convention is called cls. This is implemented with the @classmethod decorator.

The typical usage of the term "static method" in C/C++/etc applies to both Python "static" and Python "class" methods, since both of those types of methods lack a reference to the instance. In C/C++/etc, methods normally have implicit access to all non-instance members/methods of the class, which is probably why this distinction only exists in languages like Python/Ruby/etc.

share|improve this answer
    
Does a static method in C/C++ have a reference to the class object? Or just "members" of the class? Can they create new members of the class? :) – Aaron Hall yesterday
3  
@AaronHall In C/C++, there is no such thing as a class object, and you don't need a reference to it to call static methods. You just write Class::staticMethod() and that's it (as long as you aren't forbidden from calling it because staticMethod() is private or something). – Ixrec yesterday

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.