decorators execution of python -
registry = [] def register(func): print('running register(%s)' % func) registry.append(func) return func @register def f1(): print('running f1()') @register def f2(): print('running f2()') def f3(): print('running f3()') def main(): print('running main()') print('registry ->', registry) f1() f2() f3() if __name__=='__main__': main()
in above program why doesnt f1() f2() , f3() in main work if return func not used in register function
a decorator higher-order function takes function input , returns function output. decorator syntax way of calling higher order function.
the lines
@register def f1(): print('running f1()')
are equivalent lines
def f1(): print('running f1()') f1 = register(f1)
usually, decorator modifies decorated function. in case returned unmodified. -- still returned. if decorator returned nothing decorator replace f1
none
(which wouldn't useful). particular decorator called side effects (registering function). fact returns unmodified function doesn't mean isn't called.
the output see should make sense now:
running register(<function f1 @ 0x0000000001dccbf8>) running register(<function f2 @ 0x0000000003566d90>) running main() registry -> [<function f1 @ 0x0000000001dccbf8>, <function f2 @ 0x0000000003566d90>] running f1() running f2() running f3()
you used @register
twice, calls register()
twice, before main run. neither f1
nor f2
changed decorator, hence work expected when called in main()
. printed value of registry
shows decorator worked intended: registered decorated f1, f2
didn't register undecorated f3
.
on other hand, if remove line return func
decorator, see (something like):
running register(<function f1 @ 0x00000000004dcbf8>) running register(<function f2 @ 0x0000000003586d90>) running main() registry -> [<function f1 @ 0x00000000004dcbf8>, <function f2 @ 0x0000000003586d90>] traceback (most recent call last): file "c:\users\jcoleman\documents\programs\pythonscripts\socode.py", line 68, in <module> main() file "c:\users\jcoleman\documents\programs\pythonscripts\socode.py", line 64, in main f1() typeerror: 'nonetype' object not callable
the decorator still called twice -- (implicitly) returning none
. f1()
hit in main
run-time error since @ stage f1
none
, isn't callable.
see this question more on decorators.
Comments
Post a Comment