Skip to content

Instantly share code, notes, and snippets.

@dhollman
Created June 7, 2012 21:22
Show Gist options
  • Save dhollman/2891610 to your computer and use it in GitHub Desktop.
Save dhollman/2891610 to your computer and use it in GitHub Desktop.
## {{{ http://code.activestate.com/recipes/577659/ (r1)
# -*- coding: utf-8 -*-
class alias(object):
"""
Alias class that can be used as a decorator for making methods callable
through other names (or "aliases").
Note: This decorator must be used inside an @aliased -decorated class.
For example, if you want to make the method shout() be also callable as
yell() and scream(), you can use alias like this:
@alias('yell', 'scream')
def shout(message):
# ....
"""
def __init__(self, *aliases):
"""Constructor."""
self.aliases = set(aliases)
def __call__(self, f):
"""
Method call wrapper. As this decorator has arguments, this method will
only be called once as a part of the decoration process, receiving only
one argument: the decorated function ('f'). As a result of this kind of
decorator, this method must return the callable that will wrap the
decorated function.
"""
f._aliases = self.aliases
return f
def aliased(aliased_class):
"""
Decorator function that *must* be used in combination with @alias
decorator. This class will make the magic happen!
@aliased classes will have their aliased method (via @alias) actually
aliased.
This method simply iterates over the member attributes of 'aliased_class'
seeking for those which have an '_aliases' attribute and then defines new
members in the class using those aliases as mere pointer functions to the
original ones.
Usage:
@aliased
class MyClass(object):
@alias('coolMethod', 'myKinkyMethod')
def boring_method():
# ...
i = MyClass()
i.coolMethod() # equivalent to i.myKinkyMethod() and i.boring_method()
"""
original_methods = aliased_class.__dict__.copy()
for name, method in original_methods.iteritems():
if hasattr(method, '_aliases'):
# Add the aliases for 'method', but don't override any
# previously-defined attribute of 'aliased_class'
for alias in method._aliases - set(original_methods):
setattr(aliased_class, alias, method)
return aliased_class
#
# A very simple example
#
@aliased
class Vehicle(object):
def __init__(self, brand, model, color):
"""Constructor."""
self.brand = brand
self.model = model
self.color = color
@alias('modelBrandAndColor', 'getModelBrandAndColour', 'getDescription')
def model_brand_and_color(self):
"""Get the model and brand of this Vehicle."""
return '{0} {1} {2}'.format(self.color, self.brand, self.model)
vehicle = Vehicle('Chevrolet', 'Spark', 'black')
# Now your API looks like your users would want.
# Any of the following lines is equivalent to the others:
print vehicle.model_brand_and_color()
print vehicle.getDescription()
print vehicle.modelBrandAndColor()
print vehicle.getModelBrandAndColour()
## end of http://code.activestate.com/recipes/577659/ }}}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment