I'm wondering if it's possible to make a method which behaves differently when called as a class method than when called as an instance method.
For example, as a skills-improvement project, I'm writing a Matrix
class (yes, I know there are perfectly good matrix classes already out there). I've created a class method for it called identity
which returns an identity matrix of a specified size.
Now, when called on an instance of Matrix
, it seems logical that the size shouldn't need to be specified; it should return an identity matrix of the same size as the Matrix
it's called on.
In other words, I'd like to define a method which can determine whether it was called via an instance and, if so, access that instance's attributes. Unfortunately, even after digging through the documentation and a few Google searches, I haven't found anything which suggests this is possible. Does anyone know differently?
Edit:
Wow! Clearly, I'm still not quite used to first-class functions. Here's what I ended up with — thanks to Unknown for providing the key!
class Foo(object):
def __init__(self, bar):
self.baz = bar
self.bar = MethodType(lambda self: self.__class__.bar(self.baz), self, self.__class__)
@classmethod
def bar(cls, baz):
return 5 * baz
Foo.bar(3) # returns 15
foo = Foo(7)
foo.bar() # returns 35
Edit 2:
Just a quick note — this technique (and most of those presented below) won't work on classes which define __slots__
, as you cannot reassign the method.