Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A class method which behaves differently when called as an instance method?

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.

like image 785
Ben Blank Avatar asked May 14 '09 00:05

Ben Blank


People also ask

Can a class method be called on an instance?

A class method is a method that's shared among all objects. To call a class method, put the class as the first argument. Class methods can be can be called from instances and from the class itself.

What is the difference between a class method and instance method?

Key Takeaways. 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 .

How an instance method is different from a static method Python?

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).


1 Answers

Questionably useful Python hacks are my forte.

from types import *  class Foo(object):     def __init__(self):         self.bar = methodize(bar, self)         self.baz = 999      @classmethod     def bar(cls, baz):         return 2 * baz   def methodize(func, instance):     return MethodType(func, instance, instance.__class__)  def bar(self):     return 4*self.baz   >>> Foo.bar(5) 10 >>> a=Foo() >>> a.bar() 3996 
like image 108
Unknown Avatar answered Sep 21 '22 12:09

Unknown