the send method in this version compresses the incoming data before sending it on to the client now that we have these two decoratorswe can write code that dynamically switches between them when responding this example is not completebut it illustrates the logic we might follow to mix and match decoratorsclientaddr server accept(if log_sendclient loggingsocket(clientif client getpeername()[ in compress_hostsclient gzipsocket(clientrespond(clientthis code checks hypothetical configuration variable named log_send if it' enabledit wraps the socket in loggingsocket decorator similarlyit checks whether the client that has connected is in list of addresses known to accept compressed content if soit wraps the client in gzipsocket decorator notice that noneeitheror both of the decorators may be enableddepending on the configuration and connecting client try writing this using multiple inheritance and see how confused you getdecorators in python the decorator pattern is useful in pythonbut there are other options for examplewe may be able to use monkey-patchingwhich we discussed in python object-oriented shortcutsto get similar effect single inheritancewhere the "optionalcalculations are done in one large method can be an optionand multiple inheritance should not be written off just because it' not suitable for the specific example seen previouslyin pythonit is very common to use this pattern on functions as we saw in previous functions are objects too in factfunction decoration is so common that python provides special syntax to make it easy to apply such decorators to functions for examplewe can look at the logging example in more general way instead of loggingonly send calls on socketswe may find it helpful to log all calls to certain functions or methods the following example implements decorator that does just thisimport time def log_calls(func)def wrapper(*args**kwargs)now time time(