In the previous article, I created a framework with decorators as function definitions. This time, assuming that, let's implement it with Class. (Not a Class decorator, a Class definition for a function decorator)
If you need an explanation from "What is a decorator?", A previous post (" What is a decorator--make a general-purpose decorator framework for Python" msi / items / acfa737842416580deaf #% E3% 83% 87% E3% 82% B3% E3% 83% AC% E3% 83% BC% E3% 82% BFdecorator-% E3% 81% A8% E3% 81% AF) ) Please refer to the.
"[Applying decorators by class](# class-% E3% 81% AB% E3% 82% 88% E3% 82% 8B% E3% 83% 87% E3% 82% B3% E3% 83% AC% E3 % 83% BC% E3% 82% BF% E3% 81% AE% E5% BF% 9C% E7% 94% A8) ”describes how to apply a class decorator using inheritance.
decorator_class_framework.py
The decorator must be a callable object.
@my_decorator
def f(arg):
pass
The decorator notation is
def f(arg):
pass
f = my_decorator(f)
Is equivalent to That is, if you define a class called my_decorator, this class must be callable.
The first time my_decorator
is called (f = my_decorator (f)
),__init__ ()
is called.
In the above example, __init__ (f)
is called.
Then the generated instance is assigned to f. (Note that the return value of __init __ ()
is not assigned.)
When the replaced f
is called, the my_decorator
object is called. If you want to call a class object as a function, implement __call__
.
sample_001.py
class my_decorator_001:
def __init__( self, func ):
print( "called __init__" )
self._func = func
def __call__( self, *args, **kwargs ):
print( "called __call__ with args:", args, "kwargs:", kwargs )
try:
ret = self._func( *args, **kwargs )
except:
raise
print( "post func" )
return ret
@my_decorator_001
def f_001( arg1 ):
print( "in f_001 with arg1:", arg1 )
f_001( "test 001" )
Execution result 001
>>> @my_decorator_001
... def f_001( arg1 ):
... print( "in f_001 with arg1:", arg1 )
...
called __init__
>>> f_001( "test 001" )
called __call__ with args: ('test 001',) kwargs: {}
in f_001 with arg1: test 001
post func
>>>
Consider giving an argument to the decorator.
@my_decorator(arg1, arg2)
def f(arg):
pass
The decorator notation is
def f(arg):
pass
f = my_decorator(arg1, arg2)(f)
Is equivalent to In the my_decorator (arg1, arg2)
part, __init__
is called with two arguments to create an instance.
__Call__
is called with f
as an argument for the created instance.
sample_002.py
class my_decorator_002:
def __init__( self, *args, **kwargs ):
print( "called __init__ with args:", args, "kwargs:", kwargs )
self._args = args
self._kwargs = kwargs
def __call__( self, func ):
print( "called __call__ with func:", func )
def wrapper_f( *args, **kwargs ):
print( "called wrapper_f with args:", args, "kwargs:", kwargs )
try:
ret = func( *args, **kwargs )
except:
raise
print( "post func" )
return ret
return wrapper_f
@my_decorator_002( "arg1", "arg2" )
def f_002( arg1 ):
print( "in f_002 with arg1:", arg1 )
f_002( "test 002" )
Execution result 002
>>> @my_decorator_002( "arg1", "arg2" )
... def f_002( arg1 ):
... print( "in f_002 with arg1:", arg1 )
...
called __init__ with args: ('arg1', 'arg2') kwargs: {}
called __call__ with func: <function f_002 at 0x76b326a8>
>>> f_002( "test 002" )
called wrapper_f with args: ('test 002',) kwargs: {}
in f_002 with arg1: test 002
post func
>>>
Consolidate to work with or without arguments.
The call timing of __init__
, the argument of __call__
, and __call__
differs depending on the presence or absence of the argument.
Decorator arguments → | No arguments | With arguments(Including empty arguments) |
---|---|---|
__init__() |
__init__(func) |
__init__(args,...) |
__call__() |
When calling a function__call__(args,...) |
When decorating__call__(func) |
Use to determine that func
is a single callable argument. (Therefore, you can't specify any other callable object in the first argument of the decorator created in this article.)
Also specify @wraps
.
(For @wraps
, see the previous article," Final Finishing-Making a Python Decorator Framework 80% E5% BE% 8C% E3% 81% AE% E4% BB% 95% E4% B8% 8A% E3% 81% 92) ”.
sample_003.py
from functools import wraps
class my_decorator_003:
def __init__( self, *args, **kwargs ):
print( "called __init__ with args:", args, "kwargs:", kwargs )
self._func = None
self._args = []
self._kwargs = {}
if len(args) == 1 and callable(args[0]):
self._func = self._my_decorator( args[0] )
else:
self._args = args
self._kwargs = kwargs
def __call__( self, *args, **kwargs ):
print( "called __call__ with args:", args, "kwargs:", kwargs )
if self._func is None:
if len(args) == 1 and callable(args[0]):
self._func = self._my_decorator( args[0] )
return self._func
else:
try:
ret = self._func( *args, **kwargs )
except:
raise
return ret
def _my_decorator( self, func ):
print( "called _my_decorator with func:", func )
@wraps(func)
def wrapper_f( *args, **kwargs ):
print( "called wrapper_f with",
"args:", args, "kwargs:", kwargs,
"priv args:", self._args, "kwargs:", self._kwargs )
try:
ret = func( *args, **kwargs )
except:
raise
print( "post func" )
return ret
return wrapper_f
def f_003_0( arg1 ):
"""Doc Test"""
print( "in f_003_0 with arg1:", arg1 )
@my_decorator_003
def f_003_1( arg1 ):
"""Doc Test"""
print( "in f_003_1 with arg1:", arg1 )
@my_decorator_003( "arg1", arg2="arg2_str" )
def f_003_2( arg1 ):
"""Doc Test"""
print( "in f_003_2 with arg1:", arg1 )
@my_decorator_003()
def f_003_3( arg1 ):
"""Doc Test"""
print( "in f_003_3 with arg1:", arg1 )
f_003_0( "test 003" )
f_003_1( "test 003" )
f_003_2( "test 003" )
f_003_3( "test 003" )
Execution result 003
>>> def f_003_0( arg1 ):
... """Doc Test"""
... print( "in f_003_0 with arg1:", arg1 )
...
>>> @my_decorator_003
... def f_003_1( arg1 ):
... """Doc Test"""
... print( "in f_003_1 with arg1:", arg1 )
...
called __init__ with args: (<function f_003_1 at 0x7697b540>,) kwargs: {}
called _my_decorator with func: <function f_003_1 at 0x7697b540>
>>> @my_decorator_003( "arg1", arg2="arg2_str" )
... def f_003_2( arg1 ):
... """Doc Test"""
... print( "in f_003_2 with arg1:", arg1 )
...
called __init__ with args: ('arg1',) kwargs: {'arg2': 'arg2_str'}
called __call__ with args: (<function f_003_2 at 0x7697b5d0>,) kwargs: {}
called _my_decorator with func: <function f_003_2 at 0x7697b5d0>
>>> @my_decorator_003()
... def f_003_3( arg1 ):
... """Doc Test"""
... print( "in f_003_3 with arg1:", arg1 )
...
called __init__ with args: () kwargs: {}
called __call__ with args: (<function f_003_3 at 0x7697b6f0>,) kwargs: {}
called _my_decorator with func: <function f_003_3 at 0x7697b6f0>
>>> f_003_0( "test 003" )
in f_003_0 with arg1: test 003
>>> f_003_1( "test 003" )
called __call__ with args: ('test 003',) kwargs: {}
called wrapper_f with args: ('test 003',) kwargs: {} priv args: [] kwargs: {}
in f_003_1 with arg1: test 003
post func
>>> f_003_2( "test 003" )
called wrapper_f with args: ('test 003',) kwargs: {} priv args: ('arg1',) kwargs: {'arg2': 'arg2_str'}
in f_003_2 with arg1: test 003
post func
>>> f_003_3( "test 003" )
called wrapper_f with args: ('test 003',) kwargs: {} priv args: () kwargs: {}
in f_003_3 with arg1: test 003
post func
>>>
It's almost complete with sample_003.py
, but with the Class decorator, one more thing to note.
Let's decorate such a function using sample_003.py
.
sample_003_2.py
@my_decorator_003
def f_003_4():
print( "called:", f_003_4.__name__ )
When you do this ...
Execution result
>>> @my_decorator_003
... def f_003_4():
... print( "called:", f_003_4.__name__ )
...
called __init__ with args: (<function f_003_4 at 0x76927618>,) kwargs: {}
called _my_decorator with func: <function f_003_4 at 0x76927618>
>>> f_003_4()
called __call__ with args: () kwargs: {}
called wrapper_f with args: () kwargs: {} priv args: [] kwargs: {}
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 20, in __call__
File "<stdin>", line 32, in wrapper_f
File "<stdin>", line 3, in f_003_4
AttributeError: 'my_decorator_003' object has no attribute '__name__'
>>> def f_003_5():
... print( "called:", f_003_5.__name__ )
...
>>> f_003_5()
called: f_003_5
>>>
ʻAttributeError:'my_decorator_003' object has no attribute'name'is displayed and I get an error saying that the attribute
name` does not exist. Of course, what you see when you define and reference it without a decorator is as shown above.
The class doesn't have the __name__
attribute, and if you try to save it with @ wrap
, it won't create it automatically.
Must be added explicitly.
Also, if you call _my_decorator
inside __init__
, there is no __doc__
at this stage, so add that as well.
sample_004.py
from functools import wraps
class my_decorator_004:
def __init__( self, *args, **kwargs ):
print( "called __init__ with args:", args, "kwargs:", kwargs )
self._func = None
self._args = []
self._kwargs = {}
if len(args) == 1 and callable(args[0]):
self._func = self._my_decorator( args[0] )
else:
self._args = args
self._kwargs = kwargs
def __call__( self, *args, **kwargs ):
print( "called __call__ with args:", args, "kwargs:", kwargs )
if self._func is None:
if len(args) == 1 and callable(args[0]):
self._func = self._my_decorator( args[0] )
return self._func
else:
try:
ret = self._func( *args, **kwargs )
except:
raise
return ret
def _my_decorator( self, func ):
print( "called _my_decorator with func:", func )
@wraps(func)
def wrapper_f( *args, **kwargs ):
print( "called wrapper_f with",
"args:", args, "kwargs:", kwargs,
"priv args:", self._args, "kwargs:", self._kwargs )
try:
ret = func( *args, **kwargs )
except:
raise
print( "post func" )
return ret
# wrapper_Within f__name__When__doc__When operating
#Remove the setattr below
setattr( self, "__name__", wrapper_f.__name__ )
setattr( self, "__doc__", wrapper_f.__doc__ )
return wrapper_f
def f_004_0( arg1 ):
"""Doc Test 0"""
print( "in f_004_0 with arg1:", arg1 )
print( "__name__:", f_004_0.__name__ )
print( "__doc__:", f_004_0.__doc__ )
@my_decorator_004
def f_004_1( arg1 ):
"""Doc Test 1"""
print( "in f_004_1 with arg1:", arg1 )
print( "__name__:", f_004_1.__name__ )
print( "__doc__:", f_004_1.__doc__ )
@my_decorator_004( "arg1", arg2="arg2_str" )
def f_004_2( arg1 ):
"""Doc Test 2"""
print( "in f_004_2 with arg1:", arg1 )
print( "__name__:", f_004_2.__name__ )
print( "__doc__:", f_004_2.__doc__ )
@my_decorator_004()
def f_004_3( arg1 ):
"""Doc Test 3"""
print( "in f_004_3 with arg1:", arg1 )
print( "__name__:", f_004_3.__name__ )
print( "__doc__:", f_004_3.__doc__ )
f_004_0( "test 004" )
f_004_1( "test 004" )
f_004_2( "test 004" )
f_004_3( "test 004" )
Execution result
>>> def f_004_0( arg1 ):
... """Doc Test 0"""
... print( "in f_004_0 with arg1:", arg1 )
... print( "__name__:", f_004_0.__name__ )
... print( "__doc__:", f_004_0.__doc__ )
...
>>> @my_decorator_004
... def f_004_1( arg1 ):
... """Doc Test 1"""
... print( "in f_004_1 with arg1:", arg1 )
... print( "__name__:", f_004_1.__name__ )
... print( "__doc__:", f_004_1.__doc__ )
...
called __init__ with args: (<function f_004_1 at 0x768fd420>,) kwargs: {}
called _my_decorator with func: <function f_004_1 at 0x768fd420>
>>> @my_decorator_004( "arg1", arg2="arg2_str" )
... def f_004_2( arg1 ):
... """Doc Test 2"""
... print( "in f_004_2 with arg1:", arg1 )
... print( "__name__:", f_004_2.__name__ )
... print( "__doc__:", f_004_2.__doc__ )
...
called __init__ with args: ('arg1',) kwargs: {'arg2': 'arg2_str'}
called __call__ with args: (<function f_004_2 at 0x768fd540>,) kwargs: {}
called _my_decorator with func: <function f_004_2 at 0x768fd540>
>>> @my_decorator_004()
... def f_004_3( arg1 ):
... """Doc Test 3"""
... print( "in f_004_3 with arg1:", arg1 )
... print( "__name__:", f_004_3.__name__ )
... print( "__doc__:", f_004_3.__doc__ )
...
called __init__ with args: () kwargs: {}
called __call__ with args: (<function f_004_3 at 0x768fd618>,) kwargs: {}
called _my_decorator with func: <function f_004_3 at 0x768fd618>
>>> f_004_0( "test 004" )
in f_004_0 with arg1: test 004
__name__: f_004_0
__doc__: Doc Test 0
>>> f_004_1( "test 004" )
called __call__ with args: ('test 004',) kwargs: {}
called wrapper_f with args: ('test 004',) kwargs: {} priv args: [] kwargs: {}
in f_004_1 with arg1: test 004
__name__: f_004_1
__doc__: Doc Test 1
post func
>>> f_004_2( "test 004" )
called wrapper_f with args: ('test 004',) kwargs: {} priv args: ('arg1',) kwargs: {'arg2': 'arg2_str'}
in f_004_2 with arg1: test 004
__name__: f_004_2
__doc__: Doc Test 2
post func
>>> f_004_3( "test 004" )
called wrapper_f with args: ('test 004',) kwargs: {} priv args: () kwargs: {}
in f_004_3 with arg1: test 004
__name__: f_004_3
__doc__: Doc Test 3
post func
>>>
However, as I wrote in the comment, if you need to operate __name__
or __doc__
in wrapper_f ()
, do not use setattr ()
and manage it yourself. Is required.
By implementing the decorator in a class instead of a function, the following applications are possible.
sample_005.py
from functools import wraps
class My_Base:
def __init__( self ):
self._my_string = "This is Base Class"
def getstr( self ):
return self._my_string
def putstr( self, string="" ):
self._my_string = string
class my_decorator_005(My_Base):
def __init__( self, *args, **kwargs ):
super().__init__()
self._func = None
self._args = []
self._kwargs = {}
if len(args) == 1 and callable(args[0]):
self._func = self._my_decorator( args[0] )
else:
self._args = args
self._kwargs = kwargs
def __call__( self, *args, **kwargs ):
if self._func is None:
if len(args) == 1 and callable(args[0]):
self._func = self._my_decorator( args[0] )
return self._func
else:
try:
ret = self._func( *args, **kwargs )
except:
raise
return ret
def _my_decorator( self, func ):
@wraps(func)
def wrapper_f( *args, **kwargs ):
print( "called wrapper_f with",
"args:", args, "kwargs:", kwargs,
"priv args:", self._args, "kwargs:", self._kwargs )
try:
ret = func( *args, **kwargs )
except:
raise
return ret
# wrapper_Within f__name__When__doc__When operating
#Remove the setattr below
setattr( self, "__name__", wrapper_f.__name__ )
setattr( self, "__doc__", wrapper_f.__doc__ )
return wrapper_f
@my_decorator_005
def f_005(arg):
print( arg )
f_005( 'test 005' )
print( f_005.getstr() )
f_005.putstr( "new string" )
print( f_005.getstr() )
Execution result
$ python sample_005.py
called wrapper_f with args: ('test 005',) kwargs: {} priv args: [] kwargs: {}
test 005
This is Base Class
new string
$
sample_005.py
is an example of creating a decorator by inheriting a superclass, and you can call the superclass method from the target function (actually a class instance).
(I'm afraid it's a class instance even though I should have defined it as a function, but when I implement a decorator in a class, the function name always points to the class instance.)
The following example, sample_006.py
, is an example of creating a new decorator by inheriting an existing decorator.
The subclass implements _my_decorator ().
sample_006.py
from functools import wraps
class my_decorator_006:
def __init__( self, *args, **kwargs ):
self._func = None
self._args = []
self._kwargs = {}
if len(args) == 1 and callable(args[0]):
self._func = self._my_decorator( args[0] )
else:
self._args = args
self._kwargs = kwargs
print( "args and kwargs:", self._args, self._kwargs )
def __call__( self, *args, **kwargs ):
if self._func is None:
if len(args) == 1 and callable(args[0]):
self._func = self._my_decorator( args[0] )
return self._func
else:
try:
ret = self._func( *args, **kwargs )
except:
raise
return ret
def _my_decorator( self, func ):
# _my_decorator()Is implemented in a subclass
return func
# my_decorator_Inherit 006 to define a new decorator class
class new_my_decorator(my_decorator_006):
def __init__( self, *args, **kwargs ):
super().__init__( *args, **kwargs )
#Super class_my_decorator()Override
def _my_decorator( self, func ):
@wraps(func)
def wrapper_f( *args, **kwargs ):
print( "called wrapper_f with",
"args:", args, "kwargs:", kwargs,
"priv args:", self._args, "kwargs:", self._kwargs )
try:
ret = func( *args, **kwargs )
except:
raise
return ret
# wrapper_Within f__name__When__doc__When operating
#Remove the setattr below
setattr( self, "__name__", wrapper_f.__name__ )
setattr( self, "__doc__", wrapper_f.__doc__ )
return wrapper_f
@new_my_decorator
def f_006_1(arg):
print( arg )
@new_my_decorator()
def f_006_2(arg):
print( arg )
@new_my_decorator( "new_my_decorator with arg")
def f_006_3(arg):
print( arg )
print( "calling f_006s" )
f_006_1( 'test f_006_1' )
f_006_2( 'test f_006_2' )
f_006_3( 'test f_006_3' )
Execution result
$ python sample_006.py
args and kwargs: () {}
args and kwargs: ('new_my_decorator with arg',) {}
calling f_006s
called wrapper_f with args: ('test f_006_1',) kwargs: {} priv args: [] kwargs: {}
test f_006_1
called wrapper_f with args: ('test f_006_2',) kwargs: {} priv args: () kwargs: {}
test f_006_2
called wrapper_f with args: ('test f_006_3',) kwargs: {} priv args: ('new_my_decorator with arg',) kwargs: {}
test f_006_3
$
With class inheritance, superclasses can absorb the difference in how they are called with or without arguments, and subclasses can focus on implementing decorating.
__init__ ()
and __call__ ()
depending on the presence or absence of arguments.__name__
does not have an initial class attribute, so it needs to be explicitly set as a general-purpose decorator.decorator_class_framework.py
decorator_class_framework.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
###########################################
#Decorator(decorator)
###########################################
from functools import wraps
class my_decorator_base:
def __init__( self, *args, **kwargs ):
#func Argument judgment and argument storage
self._func = None
self._args = []
self._kwargs = {}
if len(args) == 1 and callable(args[0]):
#When a decorator with no arguments is called
self._func = self._wrapper( args[0] )
else:
#When a decorator with arguments is called
self._args = args
self._kwargs = kwargs
def __call__( self, *args, **kwargs ):
#Determined by the presence or absence of the func argument
if self._func is None:
if len(args) == 1 and callable(args[0]):
#When a decorator with arguments is called
self._func = self._wrapper( args[0] )
return self._func
else:
#When a decorator with no arguments is called
try:
ret = self._func( *args, **kwargs )
except:
raise
return ret
def _wrapper( self, func ):
# _wrapper()Is implemented in a subclass
@wraps
def wrapper_f( *args, **kwargs ):
return func( *args, **kwargs )
return wrapper_f
class my_decorator(my_decorator_base):
"""
for doctest
>>> @my_decorator
... def f1( arg1 ):
... print( arg1 )
...
>>> @my_decorator('mytest1')
... def f2( arg2 ):
... print( arg2 )
...
>>> @my_decorator
... def f3( arg1 ):
... print( arg1 )
... a = 1/0
...
>>> @my_decorator('mytest2')
... def f4( arg2 ):
... print( arg2 )
... a = 1/0
...
>>> try:
... f1( "Hello, World! #1" )
... except:
... print( "error #1" )
...
Pre-processing is here
called wrapper_f with args: ('Hello, World! #1',) kwargs: {} priv args: [] kwargs: {}
Hello, World! #1
Post-processing is here
>>> try:
... f2( "Hello, World! #2" )
... except:
... print( "error #2" )
...
Pre-processing is here
called wrapper_f with args: ('Hello, World! #2',) kwargs: {} priv args: ('mytest1',) kwargs: {}
Hello, World! #2
Post-processing is here
>>> try:
... f3( "Hello, World! #3" )
... except:
... print( "error #3" )
...
Pre-processing is here
called wrapper_f with args: ('Hello, World! #3',) kwargs: {} priv args: [] kwargs: {}
Hello, World! #3
error #3
>>> try:
... f4( "Hello, World! #4" )
... except:
... print( "error #4" )
...
Pre-processing is here
called wrapper_f with args: ('Hello, World! #4',) kwargs: {} priv args: ('mytest2',) kwargs: {}
Hello, World! #4
error #4
>>>
"""
def __init__( self, *args, **kwargs ):
super().__init__( *args, **kwargs )
def _wrapper( self, func ):
"""Decorator call body"""
@wraps(func)
def wrapper_f( *args, **kwargs ):
#Pre-processing is here
print( "Pre-processing is here" )
print( "called wrapper_f with",
"args:", args, "kwargs:", kwargs,
"priv args:", self._args, "kwargs:", self._kwargs )
try:
ret = func( *args, **kwargs )
except:
raise
#Post-processing is here
print( "Post-processing is here" )
return ret
# wrapper_Within f__name__When__doc__When operating
#Remove the setattr below
setattr( self, "__name__", wrapper_f.__name__ )
setattr( self, "__doc__", wrapper_f.__doc__ )
return wrapper_f
###########################################
# unitttest
###########################################
import unittest
from io import StringIO
import sys
class Test_My_Decorator(unittest.TestCase):
def setUp(self):
self.saved_stdout = sys.stdout
self.stdout = StringIO()
sys.stdout = self.stdout
def tearDown(self):
sys.stdout = self.saved_stdout
def test_decorator_noarg(self):
@my_decorator
def t1(arg0):
print( arg0 )
t1("test_decorator_noarg")
self.assertEqual(self.stdout.getvalue(),
"Pre-processing is here\n"
"called wrapper_f with args: ('test_decorator_noarg',) kwargs: {} priv args: [] kwargs: {}\n"
"test_decorator_noarg\n"
"Post-processing is here\n"
)
def test_decorator_witharg(self):
@my_decorator('with arg')
def t1(arg0):
print( arg0 )
t1("test_decorator_witharg")
self.assertEqual(self.stdout.getvalue(),
"Pre-processing is here\n"
"called wrapper_f with args: ('test_decorator_witharg',) kwargs: {} priv args: ('with arg',) kwargs: {}\n"
"test_decorator_witharg\n"
"Post-processing is here\n"
)
def test_functionname(self):
@my_decorator
def t1():
return t1.__name__
f_name = t1()
self.assertEqual( f_name, "t1" )
def test_docattribute(self):
@my_decorator
def t1():
"""Test Document"""
pass
self.assertEqual( t1.__doc__, "Test Document" )
###########################################
# main
###########################################
if __name__ == '__main__':
@my_decorator
def f1( arg1 ):
print( arg1 )
@my_decorator('mytest1')
def f2( arg2 ):
print( arg2 )
@my_decorator
def f3( arg1 ):
print( arg1 )
a = 1/0
@my_decorator('mytest2')
def f4( arg2 ):
print( arg2 )
a = 1/0
try:
f1( "Hello, World! #1" )
except:
print( "error #1" )
try:
f2( "Hello, World! #2" )
except:
print( "error #2" )
try:
f3( "Hello, World! #3" )
except:
print( "error #3" )
try:
f4( "Hello, World! #4" )
except:
print( "error #4" )
import doctest
doctest.testmod()
unittest.main()
Execution result
$ python decorator_class_framework.py
Pre-processing is here
called wrapper_f with args: ('Hello, World! #1',) kwargs: {} priv args: [] kwargs: {}
Hello, World! #1
Post-processing is here
Pre-processing is here
called wrapper_f with args: ('Hello, World! #2',) kwargs: {} priv args: ('mytest1',) kwargs: {}
Hello, World! #2
Post-processing is here
Pre-processing is here
called wrapper_f with args: ('Hello, World! #3',) kwargs: {} priv args: [] kwargs: {}
Hello, World! #3
error #3
Pre-processing is here
called wrapper_f with args: ('Hello, World! #4',) kwargs: {} priv args: ('mytest2',) kwargs: {}
Hello, World! #4
error #4
....
----------------------------------------------------------------------
Ran 4 tests in 0.003s
OK
$
unittest Execution result
$ python -m unittest -v decorator_class_framework.py
test_decorator_noarg (decorator_class_framework.Test_My_Decorator) ... ok
test_decorator_witharg (decorator_class_framework.Test_My_Decorator) ... ok
test_docattribute (decorator_class_framework.Test_My_Decorator) ... ok
test_functionname (decorator_class_framework.Test_My_Decorator) ... ok
----------------------------------------------------------------------
Ran 4 tests in 0.005s
OK
$
Recommended Posts