What's your problem?
Sometime you want to implement this pattern in your code:
>>> MyClass.method("Antonio") #1
or
>>> my_class = MyClass()
>>> my_class.method("Antonio") #2
Basically a dual method acting as classmethod (#1) or a normal method (#2).
Approaches
One way to do is simply like this:
class MyClass:
def method(self=None, name: str) -> None:
...
As opposed to this that cover only the #2:
class MyClass:
@classmethod
def method(cls, name: str) -> None:
...
Why the simple solutionw works, it's nice to have a way to "mark" the method as being special
in the same way we use @classmethod and @staticmethod.
class MyClass:
@specialmethod
def method(self, name: str) -> None:
...
self in the case of a method is the class instance, in case of a classmethod use it will be None!!
Solution
This is a class that implements a neat decorator:
class specialmethod:
def __init__(self, method):
self.method = method
def __get__(self, instance, owner):
if instance is None:
return self.wraps(None)
return self.wraps(instance)
def wraps(self, bind):
@functools.wraps(self.method)
def wrapper(*args, **kwargs):
return self.method(bind, *args, **kwargs)
return wrapper