Until like one hour ago, I was convinced that in python Foo ().bar ()
was nothing more than a short hand for Foo.bar (Foo () )
which passes the instance as first parameter. In this example the last two lines do (apparently) the same thing:
class Foo (object):
def bar (self): print "baz"
qux = Foo ()
qux.bar ()
Foo.bar (qux)
But now I have a class Animal that has a static method populate() that returns a list of all animals known to man. Also each instance of Animal has a method populate() that fills the properties of the instance with random values.
#! /usr/bin/env python
# -*- coding: utf-8 -*-
import random
animals = [ ("Bella", "cow"), ("Spike", "dog"), ("José", "iguana"), ("Tux", "penguin") ]
class Animal (object):
@staticmethod
def populate (*args): return map (lambda x: Animal (*x), animals)
def __init__ (self, name = None, species = None):
def bar (): self.name, self.species = random.choice (animals)
self.name = name
self.species = species
self.populate = bar
def __repr__ (self): return "%s of species %s" % (self.name, self.species)
print Animal.populate ()
print Animal ("Pinky", "mouse")
qux = Animal ()
qux.populate ()
print qux
The code works fine, but what made me suspicious was the fact that print Animal.populate (qux)
called the static populate method (and hence returned a list and did not populate poor qux). So apparently my conviction that Foo ().bar ()
was nothing more than a short hand for Foo.bar (Foo () )
is wrong.
This raises various questions for me:
Foo ().bar ()
?Foo.bar (Foo () )
?(Yes it must be the same name.)
The instance method acts on an object's attributes. It can modify the object state by changing the value of instance variables. Static methods have limited use because they don't have access to the attributes of an object (instance variables) and class attributes (class variables).
Instance methods need a class instance and can access the instance through self . Class methods don't need a class instance. They can't access the instance ( self ) but they have access to the class itself via cls . Static methods don't have access to cls or self .
2. Having a single implementation. Static methods are used when we don't want subclasses of a class change/override a specific implementation of a method.
On the difference between Foo().bar(), Foo.bar(Foo()) and Foo.bar() (as an answer because I signed up yesterday and can't post comments yet) - this is because of Python(<3.0)'s concept of 'bound' and 'unbound' methods - it strictly requires that, except with @staticmethod or @classmethod, method calls have an instance associated with them. There's not really any easier way to explain it than just something you have to remember. Thankfully, this has changed in Python 3 - the concept of 'bound' and 'unbound' methods as separate things has gone, and Foo.bar() works just fine for your example.
Static methods and class methods are special descriptors. Since the descriptor's __get__()
method's arguments include both the class and any relevant instance, they can screw with the arguments to the method in any way they like.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With