Skip to content

Instantly share code, notes, and snippets.

@keflavich
Forked from astrofrog/class_or_instance.py
Last active December 18, 2015 15:39
Show Gist options
  • Save keflavich/5806080 to your computer and use it in GitHub Desktop.
Save keflavich/5806080 to your computer and use it in GitHub Desktop.
import functools
class class_or_instance(object):
def __init__(self, fn):
self.fn = fn
def __get__(self, obj, cls):
if obj is not None:
return lambda *args, **kwds: self.fn(obj, *args, **kwds)
else:
return lambda *args, **kwds: self.fn(cls, *args, **kwds)
from functools import update_wrapper
class class_or_instanceb(object):
def __init__(self, fn):
self.fn = fn
def __get__(self, obj, cls):
if obj is not None:
f = lambda *args, **kwds: self.fn(obj, *args, **kwds)
else:
f = lambda *args, **kwds: self.fn(cls, *args, **kwds)
# update the function to have the correct metadata
# f = decorator(f, self.fn)
update_wrapper(f, self.fn)
return f
# this approach fails, and has an extra dependency
#from decorator import decorator
#
#class class_or_instancec(object):
# def __init__(self, fn):
# self.fn = fn
# def __get__(self, obj, cls):
# if obj is not None:
# def wrap_obj(f, *args, **kwargs):
# f(obj, *args, **kwargs)
# return decorator(wrap_obj, self.fn)
# else:
# def wrap_cls(f, *args, **kwargs):
# f(cls, *args, **kwargs)
# return decorator(wrap_cls, self.fn)
class SimpleQueryClass(object):
@class_or_instance
def query(self):
""" docstring """
if self is SimpleQueryClass:
print("Calling query as class method")
return "class"
else:
print("Calling query as instance method")
return "instance"
@class_or_instanceb
def queryb(self):
""" docstring """
if self is SimpleQueryClass:
print("Calling query as class method")
return "class"
else:
print("Calling query as instance method")
return "instance"
# @class_or_instancec
# def queryc(self):
# """ docstring """
# if self is SimpleQueryClass:
# print("Calling query as class method")
# return "class"
# else:
# print("Calling query as instance method")
# return "instance"
from class_or_instance import SimpleQueryClass
print "queryb = functools.update_wrapper approach, query = lambda approach"
print "SimpleQueryClass.query.__doc__:",SimpleQueryClass.query.__doc__
print "SimpleQueryClass.queryb.__doc__:",SimpleQueryClass.queryb.__doc__
print "SimpleQueryClass.query():",SimpleQueryClass.query()
print "SimpleQueryClass.queryb():",SimpleQueryClass.queryb()
U = SimpleQueryClass()
print "U.query.__doc__:",U.query.__doc__
print "U.queryb.__doc__:",U.queryb.__doc__
print "U.query():",U.query()
print "U.queryb():",U.queryb()
assert SimpleQueryClass.query() == "class"
assert SimpleQueryClass.queryb() == "class"
assert U.query() == "instance"
assert U.queryb() == "instance"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment