Skip to content

Instantly share code, notes, and snippets.

@heyimalex
Last active August 29, 2015 13:59
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save heyimalex/10759806 to your computer and use it in GitHub Desktop.
Call Descriptor
"""
Call Descriptor
~~~~~~~~~~~~~~~
Allows you to dynamically modify an instance's __call__ value.
You may be asking, why not just use an attribute on the object
instead of this magical descriptor?
Good fucking question...
"""
class CallDescriptor(object):
def __get__(self, obj, objtype):
return obj.__call__
def __set__(self, obj, val):
self.__delete__(obj)
NewClass = type(
"Callable"+obj.__class__.__name__,
(obj.__class__,),
{'__call__': val}
)
obj.__class__ = NewClass
def __delete__(self, obj):
if callable(obj):
obj.__class__ = obj.__class__.__bases__[0]
from descriptor import CallDescriptor
class A(object):
call = CallDescriptor() # Must not be in instance
a = A()
print callable(a) # False
a.call = lambda self: "Hello world!"
print callable(a) # True
print a() # "Hello World!"
# Doesn't modify the original class
b = A()
print callable(b) # False
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment