class bindclass(object):
    def __init__(self, f):
        self.f = f
    def bind(self, cls, attr):
        def bound_m(*args, **kwargs):
            return self.f(cls, *args, **kwargs)
        bound_m.__name__ = attr
        self.m = bound_m
    def __get__(self, obj, objtype=None):
        return self.m.__get__(obj, objtype)

class Type(type):
    def __init__(self, name, bases, attrs):
        for attr, val in attrs.iteritems():
            if isinstance(val, bindclass):
                val.bind(self, attr)

class Object(object):
    __metaclass__ = Type


def bindfunction(f):
    def bound_f(*args, **kwargs):
        return f(bound_f, *args, **kwargs)
    bound_f.__name__ = f.__name__
    return bound_f

class Foo(Object):
    @bindclass
    def foo(this_class, self):
        return this_class, self

class Bar(Foo):
    @bindclass
    def bar(this_class, self):
        return this_class, self

f = Foo()
b = Bar()

@bindfunction
def factorial(this_function, n):
    if n > 0:
        return n * this_function(n - 1)
    else:
        return 1