Hi all,

I have been trying out to wrap my mind around the advantages of decorators and thought I found a use in one of my experiments. (see code after my sig).

Although it works, I think it should be able to do it better.
My particular problem is that I want to remove an argument (say always the first one) when the decorated function is called.

However if the function is defined in a class the first argument is self and thus the second argument should be removed.

Since I like to have a more general DRY approach I want to test if the decorated function is defined in a class or not thus knowing that the first argument is self and must be preserved.

I tried different approaches but all didn't work and looked very unpythonic (looking at the attributes, descriptors namespaces, id() of the function, the first argument and the decorator itself).

So is there a way to find out if the first argument is 'self' without making a false positive if the first argument is a class instance passed to a function?

--
MPH
http://blog.dcuktec.com
'If consumed, best digested with added seasoning to own preference.'

code:
class Decorator(object):
    "When used as Decorator(argument) returns a decorator"
    def __init__(self, key):
        self.key = key

    def __call__(self, function):
        "Return a decorator"
        def decorator(*arg_tuple, **arg_dict):
            "The decorator test if the arguments contain a valid key"
            if arg_tuple[0] == self.key:
                # This means it is a simple function, so check and strip it
                arg_list = arg_tuple[1::]
                return(function(*arg_list, **arg_dict))
            elif arg_tuple[1] == self.key:
                # This means it is a class method, check it,
                # strip (but retain self)
                arg_list = arg_tuple
                arg_list = arg_list[0:1] + arg_list[2::]
                return(function(*arg_list, **arg_dict))
            else:
                # The key was invalid
                return('invalid')

        return(decorator)


class Test(object):
    @Decorator('key')
    def test(self, data):
        return(data)

    @Decorator('key')
    def function_2(self, data):
        return(data)

    @Decorator('key')
    def function_3(self, data):
        return(data)


@Decorator('key')
def test_f(data):
    return(data)

# Test starts here
test_c = Test()
print(test_c.test('key', 'data'))
print(test_f('key', 'data'))
print(test_c.test('invalid', 'data'))
print(test_f('invalid', 'data'))
--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to