method that can be called from a class and also from an instance
Peter Otten
__peter__ at web.de
Fri Nov 23 03:52:25 EST 2012
Steven D'Aprano wrote:
> On Thu, 22 Nov 2012 16:51:27 +0100, Peter Otten wrote:
>
>> Marc Aymerich wrote:
>>
>>> Hi,
>>>
>>> I want to create a method within a class that is able to accept either
>>> a class or an instance.
> [...]
>> Why would you overload a method that way?
>
>
> The use-case I have is that I have a number of classes with default
> state. Most instances don't override any of the state, so the instances
> don't add anything except an extra conceptual layer:
>
> instance = MyClass() # notice that there are no arguments passed
> instance.method(args)
>
> Since the instances don't have any state except for that already held by
> the class, they are redundant and pointless. Just knowing the class is
> enough to specify the behaviour. If I used class methods, I could do this:
>
> MyClass.method(args)
>
>
> But here's the thing -- sometimes I *do* have instances that override the
> default state:
>
> instance = MyClass(x, y, z)
> instance.method(args)
>
> Now if method is a class method, my per-instance state is ignored. So I
> want a method that can be called from the class, and see the default
> state, or from the instance, and see the per-instance state. Neither
> classmethod, staticmethod nor ordinary instance methods do the job, but
> my custom dualmethod does.
>
> http://code.activestate.com/recipes/577030/
Am I reading that right that you don't invoke method() as MyClass.method()?
Then I'd probably use class attributes to store the default state and shade
them by instance attributes as needed.
class A:
state = "default"
def __init__(self, state=None):
if state is not None:
self.state = state
def method(self): return self.state
assert A().method() == "default"
assert A("special").method() == "special"
The same idea might work for the OP, too (but I'm not sure it's a good
idea):
class B:
def inst_f(self):
return "instance"
@classmethod
def f(class_):
return "class"
def __init__(self):
self.f = self.inst_f
assert B.f() == "class"
assert B().f() == "instance"
More information about the Python-list
mailing list