Jake
Jake

Reputation: 13141

Can a method be used as either a staticmethod or instance method?

I'd like to be able to do this:

class A(object):
    @staticandinstancemethod
    def B(self=None, x, y):
        print self is None and "static" or "instance"

A.B(1,2)
A().B(1,2)

This seems like a problem that should have a simple solution, but I can't think of or find one.

Upvotes: 5

Views: 651

Answers (4)

Keith
Keith

Reputation: 43024

The answer to your question is no, you can't do that.

What I would do, since Python also supports regular functions, is define a function outside that class, then call that function from a normal method. The caller can decide what which one is needed.

Upvotes: -3

sasker
sasker

Reputation: 2321

From what you're saying, is this along the line of what you're looking for? I'm not sure there is a way to do exactly what you're saying that is "built in"

class Foo(object):
    def __init__(self, a=None, b=None):
        self.a
        self.b

    def Foo(self):
        if self.a is None and self.b is None:
            form = CreationForm()
        else: 
            form = EditingForm()
        return form

Upvotes: 0

Ian B.
Ian B.

Reputation: 243

It is possible, but please don't. I couldn't help but implement it though:

class staticandinstancemethod(object):
     def __init__(self, f):
          self.f = f

     def __get__(self, obj, klass=None):
          def newfunc(*args, **kw):
               return self.f(obj, *args, **kw)
          return newfunc

...and its use:

>>> class A(object):
...     @staticandinstancemethod
...     def B(self, x, y):
...         print self is None and "static" or "instance"

>>> A.B(1,2)
static
>>> A().B(1,2)
instance

Evil!

Upvotes: 9

jsbueno
jsbueno

Reputation: 110166

Since you'd like the static method case to be used to create a new class anyway, you'd best just make it a normal method and call it at the end of the __init__ method.

Or, if you don't want that, create a separate factory function outside the class that will instantiate a new, empty object, and call the desired method on it.

There probably are ways of making exactly what you are asking for, but they will wander through the inner mechanisms of Python, be confusing, incompatible across python 2.x and 3.x - and I can't see a real need for it.

Upvotes: 0

Related Questions