1
def suppress(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        try:
            return func(*args, **kwargs)
        except Exception:
            pass
    return wrapper
def myfunc():
    print("foo")
    print("foo")

I found this code in a book, and ran it how it said...

suppress(myfunc)

The book said it was supposed to run the function but suppress the error in it, which was in print("foo") Instead, it just gave me...

<function myfunc at 0x6981e0>

Why???

1
  • 2
    Because that's what suppress does: it takes one function and gives you another function. If you want to call that function, go right ahead, call it: suppress(myfunc)() (notice extra parentheses at end of this to call the function. Commented Mar 30, 2012 at 20:26

2 Answers 2

2

Your suppress function is designed as a decorator, so you need to apply it to your functions/methods. The idiomatic way is to use the @ syntax, like you did with functools.wraps.

import functools

def suppress(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        try:
            return func(*args, **kwargs)
        except Exception:
            pass
    return wrapper

@suppress  # <-------- this is the idiomatic fix
def myfunc():
    "documentation"
    print("foo")
    raise ValueError

def myfunc2():
    "documentation"
    print("foo")
    raise ValueError

myfunc()  # prints "foo", does not raise exception
print myfunc.__doc__  # prints "documentation"

suppress(myfunc2)()  # functional style; prints "foo", does not raise exception
print suppress(myfunc2).__doc__  # prints "documentation"
Sign up to request clarification or add additional context in comments.

2 Comments

You're implying there is something special about decorator functions. There isn't. It's just a nicer synax for myfunc = supress(myfunc). So no, you don't need to apply suppress as a decorator.
Depends on what your definition of "need" is :-) I just meant that he needs to apply it somehow. Although the @ syntax is a little bit different (for recursion), here I agree the two ways to apply suppress are equivalent.
1

It seems there is a typo in your code example above. That code will not run because Python cannot parse it (SyntaxError on line 11). If you correct that perhaps we can see what is really wrong.

Regarding usage of decorators, to see this suppress in action, you should be doing:

@suppress
def myfunc():
    ...
# errors suppressed in this call
myfunc()

3 Comments

I edited his question. I do not think the parse error is part of the substance of the question.
The syntax error has to do with youpasting the code as is in an itnerpreter, withotu separating the two independent code blocks. The code would run in a program as is - you have to add a newline there.
No, the original code was just recently edited. It previously read print("foo) on the last line.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.