-
-
Save pauricthelodger/dff1a129d2fca936d87a2041c14180c7 to your computer and use it in GitHub Desktop.
A descriptor that wraps a method that can be called on a class or an instance.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from functools import wraps | |
class SometimesClassmethod: | |
def __init__(self, wrapped_function): | |
self._wrapped = wrapped_function | |
def __get__(self, instance, owner=None): | |
if instance is None: | |
return self._class_call(owner) | |
else: | |
return self._instance_call(instance, owner) | |
def _class_call(self, cls): | |
@wraps(self._wrapped) | |
def class_call(*args, **kwargs): | |
self._wrapped(cls, None, *args, **kwargs) | |
return class_call | |
def _instance_call(self, instance, cls): | |
@wraps(self._wrapped) | |
def instance_call(*args, **kwargs): | |
self._wrapped(cls, instance, *args, **kwargs) | |
return instance_call | |
def sometimes_classmethod(fn): | |
return SometimesClassmethod(fn) | |
class MyClass: | |
@sometimes_classmethod | |
def my_method(cls, self, name): | |
"""This is a method that can be called on a class or an instance.""" | |
if self is None: | |
print(f"This was called on a class, {cls.__name__}, {name}!") | |
else: | |
print(f"This was called on an instance, {self}, {name}!") | |
MyClass.my_method("Mark") | |
mine = MyClass() | |
mine.my_method(name="Judy") | |
print(MyClass.my_method.__doc__) | |
print(mine.my_method.__doc__) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment