this syntax allows us to build up decorated function objects dynamicallyjust as we did with the socket exampleif we don' replace the namewe can even keep decorated and non-decorated versions for different situations often these decorators are general modifications that are applied permanently to different functions in this situationpython supports special syntax to apply the decorator at the time the function is defined we've already seen this syntax when we discussed the property decoratornowlet' understand how it works instead of applying the decorator function after the method definitionwe can use the @decorator syntax to do it all at once@log_calls def test ( , , )print("\ttest called"the primary benefit of this syntax is that we can easily see that the function has been decorated at the time it is defined if the decorator is applied latersomeone reading the code may miss that the function has been altered at all answering question like"why is my program logging function calls to the console?can become much more difficulthoweverthe syntax can only be applied to functions we definesince we don' have access to the source code of other modules if we need to decorate functions that are part of somebody else' third-party librarywe have to use the earlier syntax there is more to the decorator syntax than we've seen here we don' have room to cover the advanced topics hereso check the python reference manual or other tutorials for more information decorators can be created as callable objectsnot just functions that return functions classes can also be decoratedin that casethe decorator returns new class instead of new function finallydecorators can take arguments to customize them on per-function basis the observer pattern the observer pattern is useful for state monitoring and event handling situations this pattern allows given object to be monitored by an unknown and dynamic group of "observerobjects whenever value on the core object changesit lets all the observer objects know that change has occurredby calling an update(method each observer may be responsible for different tasks whenever the core object changesthe core object doesn' know or care what those tasks areand the observers don' typically know or care what other observers are doing