0

I've 2 questions. I've created a decorator which checks whether the dictionary has a key or not? Here it is.

def check_has_key(func):
    def inner(x,y): # inner function needs parameters
        dictionary = {"add" : "true", "subtract" : "true"}
        if dictionary.has_key("add") : 
            return func(x,y)
        return "Add not allowed"
    return inner # return the inner function (don't call it)

@check_has_key
def add(x,y):
    return x+y

print add(1,2)

1) Can I pass the key as an argument to the wrapper and then check whether it exists or not? For eg :- like I just pass the key as @check_has_ket("subtact").

2) Can I use a decorator inside the function? as in if I need to check whether the dictionary has the key or not, deep down the function?

EDIT

I got the answer for the 1st question.

def abc(a):
    def check_has_key(func):
        def inner(x,y): # inner function needs parameters
            dictionary = {"add" : "true", "subtract" : "true"}
            if dictionary.has_key(a) : 
                return func(x,y)
            return "Add not allowed"
        return inner # return the inner function (don't call it)
    return check_has_key

@abc("subtract")
def add(x,y):
    return x+y

print add(1,2)

But my doubt still remains can I use the decorator deep down the function? Meaning if I need to check whether a key exist in the dictionary or not deep down the function , can I use the decorator for this purpose or will I have to use the if condition only?

python-coder
  • 2,128
  • 5
  • 26
  • 37
  • Why are you defining the dictionary _inside_ the inner function? Wouldn't `dictionary.has_key` will always be true then? And what is your goal on creating the decorator function anyway? By the way, you can use decorators wherever you define a function. – aIKid Jan 25 '14 at 09:36
  • (1) Are decorators only used when defining a function or can I use just like that also, meaning in between the lines or codes? (2) in which order does the decorators execute, if I have multiple decorators on 1 function? – python-coder Jan 25 '14 at 09:46
  • Perhaps this [answer](http://stackoverflow.com/a/1594484/1672128) on decorators may help. Read it, it's like everything you need to know about decorators. – YS-L Jan 25 '14 at 09:55
  • Your remaining doubt about using a decorator "deep down the function": You can use it anywhere you want, either via @ syntax on a (nested) function definition or explicitly to modify an existing one, i.e. `foo = abc("add")(foo)`. – martineau Jan 25 '14 at 10:07

1 Answers1

0

If you need to parameterize your decorator, you can define a class, pass in your arguments for the decorator via __init__ and override its __call__ function. Something like:

class decorate:

    def __init__(self, decorator_arg):
        self.decorator_arg = decorator_arg

    def __call__(self, func):
        def inner(x,y):
            # do something, probably using self.decorator_arg
            return func(x,y)
        return inner

@decorate("subtract")
def add(x,y):
    return x+y

For (2), yes if you have another function to decorate within your function. If you need to do such thing, you probably just need a function instead of a decorator.

YS-L
  • 14,358
  • 3
  • 47
  • 58
  • I know if there's a nested function I can use the decorator, but in my case there's no nested function. It's just the plain set of lines of codes. Also please see my edited question, and check I've done (1) in my way. Is it correct way of doing it?? – python-coder Jan 25 '14 at 09:39
  • Yes, your way for (1) is perfectly fine as well. Decorator is meant to be used to _decorate a function_, if there isn't another function, you simply don't need a decorator. You just need another function that can be reused in multiple places. If the decorated function has to know that _it_ has been decorated, or even need to touch that decorator inside it's body, you are using decorator the wrong way. – YS-L Jan 25 '14 at 09:50
  • in which order does the decorators execute, if I have multiple decorators on 1 function? – python-coder Jan 25 '14 at 09:59
  • A bit difficult to describe in comments, but anyway -- the decorator that is closest to the original function (i.e. immediately above the ``def`` of the decorated function) will first wrap the original function, resulting in a wrapped function which will then be wrapped by the next upper decorator, resulting in another function which ... and so on. – YS-L Jan 25 '14 at 11:05