-
-
Save keflavich/5806080 to your computer and use it in GitHub Desktop.
This file contains 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
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" |
This file contains 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 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