import types
class ClassOrInstanceMethod(object):
def __init__(self, wrapped):
self.wrapped = wrapped
def __get__(self, instance, owner):
if instance is None:
instance = owner
return self.wrapped.__get__(instance, owner)
class demo(object):
@ClassOrInstanceMethod
def foo(self):
# self will be the class if this is called on the class
print(self)
demo.foo()
demo().foo()
aW1wb3J0IHR5cGVzCgpjbGFzcyBDbGFzc09ySW5zdGFuY2VNZXRob2Qob2JqZWN0KToKICAgIGRlZiBfX2luaXRfXyhzZWxmLCB3cmFwcGVkKToKICAgICAgICBzZWxmLndyYXBwZWQgPSB3cmFwcGVkCiAgICBkZWYgX19nZXRfXyhzZWxmLCBpbnN0YW5jZSwgb3duZXIpOgogICAgICAgIGlmIGluc3RhbmNlIGlzIE5vbmU6CiAgICAgICAgICAgIGluc3RhbmNlID0gb3duZXIKICAgICAgICByZXR1cm4gc2VsZi53cmFwcGVkLl9fZ2V0X18oaW5zdGFuY2UsIG93bmVyKQoKY2xhc3MgZGVtbyhvYmplY3QpOgogICAgQENsYXNzT3JJbnN0YW5jZU1ldGhvZAogICAgZGVmIGZvbyhzZWxmKToKICAgICAgICAjIHNlbGYgd2lsbCBiZSB0aGUgY2xhc3MgaWYgdGhpcyBpcyBjYWxsZWQgb24gdGhlIGNsYXNzCiAgICAgICAgcHJpbnQoc2VsZikKCmRlbW8uZm9vKCkKZGVtbygpLmZvbygp