+ 7

Help me in Printing 2 functions in same decorator

def decor(func): def wrap(): print("============") func() print("============") return wrap @decor def print_text(): print("Hello world!") def print_text2(): print("python") print_text() Print_text2() Expected Output: ========== Hello word Python ==========

24th Oct 2020, 2:12 PM
shahul hameed
shahul hameed - avatar
14 ответов
+ 10
You can change your code to this , def decor(func,func2): def wrap(): print("============") func() func2() print("============") return wrap def print_text(): print("Hello world!") def print_text2(): print("python") main_func=decor(print_text,print_text2) main_func()
24th Oct 2020, 2:17 PM
Abhay
Abhay - avatar
+ 9
Abhay good idea! reveals the architecture of decorators.
24th Oct 2020, 3:07 PM
Oma Falk
Oma Falk - avatar
+ 8
It might help to see this subtle distinction more clearly if you saw how the decorator pattern is actually implemented. Take this original version of the code: @decor def print_text(): print("Hello world!") Using Abhay's solution, the print_text function is passed in and then returned as an enclosed function wrapped within a new closure function. enclosed_func = decor(print_text) enclosed_func() This new behavior is executed using the new function as seen above. However, the decorator pattern is implemented using: print_text = decor(print_text) print_text() As you can see, the original interface is still preserved with the extended behavior... hence... decorating the original function.
25th Oct 2020, 6:02 PM
David Carroll
David Carroll - avatar
+ 7
There seems to be some misunderstanding of the decorator pattern. Decorators are meant to extend the behavior of a function without changing the interface of that function. The response from Abhay provides a solution for the end result, but it's no longer utilizing a decorator pattern. Rather, his solution is returning an enclosed function (via closure with no private state) to delegate the work of two different functions to a completely new function. While this is similar to how decorators are being implemented in Python, the key missing characteristic here is the original function interface must be changed to execute the desired change. Again, I'm not taking away from the solution, just clarifying the solution doesn't involve using a decorator.
25th Oct 2020, 5:44 PM
David Carroll
David Carroll - avatar
+ 6
Moreover, a decor just adding 2 functions: def decor_add(func,func2): def added(): func() func2() return added in your case, together=decor_add(print_text,print_text2) main=decor(together) (if decor is defined, as wanted from you...)
24th Oct 2020, 3:38 PM
Alexander Thiem
Alexander Thiem - avatar
+ 6
If you're asking for an example of decorator pattern in C++ as applied to a function similar to how it's done in Python... I'm not your guy. Even if it was possible, I believe seeing a C++ equivalent will only confuse you more. The approach for implementing decorators in Python involves: 1.) Using inner functions and closures in a technique known as Higher Order Functions (HOF) where a function takes another function as an argument and returns, yet another function. 2.) Assigning the original function with the new function using a technique known as monkey patching - something that's common in dynamic typed languages. For many reasons beyond the scope of this thread, HOF in C++ looks quite different than in Python. I'm not aware of any options to accomplish #2 in C++. Consequently, C++ would implement a decorator solution that looks completely different using techniques and features not supported in Python, such as, working with type casting, templates and generics, and function pointers.
25th Oct 2020, 8:52 PM
David Carroll
David Carroll - avatar
+ 5
Alexander Thiem The term interface refers to a method signature which could include a number of parts such as: - Function Name - Input Parameter(s) - Return Value (loose in Python) Interfaces are very loosely defined in Python since it's a dynamically typed language. So, the input parameter interface will be limited to the number of parameters and the position of those parameters as expected by the function. Example: def divide(x, y): return x / y The function name is "divide", which is part of its interface to call the function. Another part of its interface is two input arguments are expected to be provided and to follow a specific order. Technically, the interface for defining a return type / value vs void isn't really possible in most dynamic languages. Python always returns None if return isn't explicitly used. So that interface may not apply here. In static typed languages, the parameter types and return type vs void would be part of the interface.
25th Oct 2020, 6:23 PM
David Carroll
David Carroll - avatar
+ 4
David Carroll ty for your response
25th Oct 2020, 5:57 PM
Abhay
Abhay - avatar
+ 3
Ahh, so the function name should not change? Like this: https://code.sololearn.com/c4Qx4orlrrdG/?ref=app
25th Oct 2020, 6:21 PM
Alexander Thiem
Alexander Thiem - avatar
+ 3
Alexander Thiem Your updated example doesn't demonstrate a decorator pattern either. While, yes, preserving the name is part of it, this would need to apply to the source code, not at runtime. Your example is making use of dynamically updating closures to change behavior based on mutating state after each loop iteration. You just happen to also preserve the function name while in execution.
25th Oct 2020, 6:31 PM
David Carroll
David Carroll - avatar
+ 3
David Carroll Could you maybe give a short example in C++, where it is well defined?
25th Oct 2020, 7:16 PM
Alexander Thiem
Alexander Thiem - avatar
+ 2
what means interface in this context?
25th Oct 2020, 5:47 PM
Alexander Thiem
Alexander Thiem - avatar
+ 2
It is realy tough
25th Oct 2020, 8:56 PM
and I Channels Limited
and I Channels Limited - avatar
+ 2
David Carroll Ohhh, aleight
26th Oct 2020, 1:06 PM
Alexander Thiem
Alexander Thiem - avatar