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?
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
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.
C# - To use Partial Classes, or Seperate Ones? [duplicate]
php5 extend main class and use statics
Call pure virtual function from parent class
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
Should I refactor static nested classes in Java into separate classes?
Can I instantiate a PHP class inside another class?
some kind off variable problem within php class
class Foo(object): def _bar(self, baz): print "_bar, baz:", baz def __init__(self, bar): self.bar = self._bar self.baz = bar @classmethod def bar(cls, baz): print "bar, baz:", baz In : import foo In : f = foo.Foo(42) In : f.bar(1) _bar, baz: 1 In : foo.Foo.bar(1) bar, baz: 1 In : f.__class__.bar(1) bar, baz: 1
What term is used to describe when two classes depend on each other?
Using the above:.
class cls_or_inst_method(object): def __init__(self, class_method, instance_method): self.class_method = class_method self.instance_method = instance_method def __get__(self, obj, objtype): if obj is None: return self.class_method else: return lambda: self.instance_method(obj) def my_class_method(baz): return baz + 1 def my_instance_method(self): return self.baz * 2 class Foo(object): baz = 10 bar = cls_or_inst_method(my_class_method, my_instance_method)
>>> print Foo.bar(5) 6 >>> my_foo = Foo() >>> print my_foo.bar() 20
The second definition of 'bar' clobbers the first definition of 'bar'.
. Try to think of unique names for your classmethod and instance method.
@classmethod def create(cls, baz): ...
def rubber_stamp(self): ...
If you're not familiar with lambda, it creates an anonymous function.
class Matrix(object): def __init__(self): self.identity = lambda s=self:s.__class__.identity(s) #...whatever initialization code you have...
self.size = 10 @classmethod def identity(self, other): #...always do you matrix calculations on 'other', not 'self'...
return other.size m = Matrix() print m.identity() print Matrix.identity(m)
It's rarely necessary, but it can make your code more concise.
The lambda line above could be rewritten:.
def identity(self): self.__class__.indentity(self) self.identity = identity