I'm trying to create a decorator class that counts how many times a function is called, but I'm getting an error message that says:
"TypeError: __exit__() takes exactly 1 argument (4 given)"
and I really don't know how I'm giving it four arguments. My code looks like this:
class fcount2(object): __instances = {} def __init__(self, f): self.__f = f self.__numcalls = 0 fcount2.__instances[f] = self def __call__(self, *args, **kwargs): self.__numcalls += 1 return self.__f(*args, **kwargs) def __enter__(self): return self def __exit__(self): return self @staticmethod def count(f): return fcount2.__instances[self.__f].__numcalls @fcount2 def f(n): return n+2 for n in range(5): print f(n) print 'f count =',f.count def foo(n): return n*n with fcount2(foo) as g: print g(1) print g(2) print 'g count =',g.count print 'f count =',f.count with fcount2(f) as g: print g(1) print g(2) print 'g count =',g.count print 'f count =',f.count with f: print f(1) print g(2) print 'g count =',g.count print 'f count =',f.count
Are there some other parameters I should (or shouldn't) be passing into the def exit function? Any tips or ideas would be appreciated.
As an aside, my line of code that says "print 'f count =',f.count" appears to be outputting the memory address rather than the value, but that's a whole different problem.
__exit__ in Python Context manager is used for managing resources used by the program. After completion of usage, we have to release memory and terminate connections between files.
__enter__ and [__exit__] both are methods that are invoked on entry to and exit from the body of "the with statement" (PEP 343) and implementation of both is called context manager. the with statement is intend to hiding flow control of try finally clause and make the code inscrutable.
Python exit commands: quit(), exit(), sys. exit() and os. _exit() The functions quit() , exit() , sys.
__exit__() documentation: If an exception is supplied, and the method wishes to suppress the exception (i.e., prevent it from being propagated), it should return a true value. Otherwise, the exception will be processed normally upon exit from this method.
the __exit__()
method should accept information about exceptions that come up in the with:
block. See here.
The following modification of your code works:
def __exit__(self, exc_type, exc_value, tb): if exc_type is not None: traceback.print_exception(exc_type, exc_value, tb) # return False # uncomment to pass exception through return True
Then you can try raising an exception in one of your with:
blocks and it'll be caught in __exit__()
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With