Nesting Functions and Decorators (2/2) (Theory of Python) (Python Tutorial)

preview_player
Показать описание
Let's continue with lots of examples of contrived decorators. These correspond to decorators I have used in practice.

Thank you!
Рекомендации по теме
Комментарии
Автор

Thanks Real Physics for one of the great basic concept. Same works in JavaScript as "Closure"

""" 1 """
def adder(x):
def wrapper(y):
return x + y
return wrapper

print(adder(4)(9))


""" 2 """
def add(x, y):
return x + y

def partial(func, x):
def wrapper(y):
return func(x, y)
return wrapper

print(partial(add, 4)(8))


""" 3 """
def make_summator():
value = 0
def wrapper(x):
nonlocal value
value += x
return value
return wrapper

summator = make_summator()
print(summator(1))
print(summator(2))
print(summator(5))


""" 4 """
def cache(func):
value = None
def wrapper(x, y):
nonlocal value
if value == None:
value = func(x, y)
return value
return wrapper

@cache
def add(x, y):
return x+y

print(add(3, 5))
print(add(1, 2))
print(add(2, 1))

alexeyk
Автор

Sir you've been pushing humanity forwards with these videos

analisededadoscompython
Автор

I managed to watch 18 videos in 3 days. I notice that each video on the playlist has less and less views/likes. Kinda sad, because i personally love the way you explain stuff. Very thorough and structured. I love it. Much better than all the other flashy tutorials that skip a lot of important details. Thanks for making these videos!

grzegorzgrzelczyk
Автор

This was fun. Thanks for great series Real Physics!

Here is my cache implementation, if anybody is still interested:

def cache(fn):
result = fn

def wrapper(n1, n2):
nonlocal result
if callable(result): # test whether 'result' refers to a function
result = fn(n1, n2)
return result
return wrapper

gibarian
Автор

Thanks man! now I have a pretty good grasp of this concept

akramznini
Автор

working off metroid kings comment/replies, i was able to come up with the following for the second hw problem:

def partial(fn, c):
def wrapper(fn):
return fn + c
return wrapper

def add(a, b):
return a + b

print(partial(add, 1)(3))


this one gave me a headache:

def make_summator():
total = 0
def wrapper(a):
nonlocal total
total += a
return total
return wrapper

summator = make_summator()

print(summator(1))

>>>1
print(summator(2))
>>>3

iMerkinator
Автор

I know it's been 3 years since you've posted this but I have experienced some problems with the remember decorator (6:30 in video). Particularly it doesn't work in Pycharm (yet it does work in the interactive mode and through console in pycharm). I was wondering whether there is a solution for this in pycharm (pycharm tells me that the 'last_fn(1, 2)' is not callable).

matis
Автор

6:55 I have a situation where I am inheriting a class from SMTPServer and I would like to add in a new method smtp_AUTH, but I don't want to completely copy/redefine/override smtp_HELP or smtp_EHLO (though I probably will have to) if the stdlib were designed differently/better would it use some decorator to allow smtpd extension? I am thinking a decorator that would record whether a method is something that may need to be listed in smtp_HELP or smtp_EHLO this would be added to a list or map or something, and looked up when when HELP happens without any arguments, or when invalid arguments happen, to give a list of HELP lines. and looked up when EHLO happens to give a list of features.

so questions are

1. Is it a good idea to use a decorator in the standard library portion of smtpd?

2. Am I understanding your @remember decorator correctly, and would this idea be a good use of such things?

3. If its not a good use, what aspect would be complained about the most? the fact it is decorators? more maintenance? changing the standard library? security?

You can see a client implementation of auth in the standard library smtplib.

bagok
Автор

I know I'm way to late for this but I'll take my chances. I can't wrap my head around to which function wrapper points when the namespace of twofloats is created and also I can't understand how wrapper accepts the parameters from add.

gualdim
Автор

I'm stuck on the adder problem, where I'm supposed to call adder(5)(3) to get 8. I have two functions created, and I guess I have a decorator set up, but I don't know how to proceed from there. I know you have chain two decorators on the adder function..I just don't understand at this point, but I know @a@ b fn = a(b(fn())).








def acceptor(func):
def wrapper1(f, x):
return func(f, x)
return wrapper
1

def adder(func):
def wrapper2(f, x):
return
return wrapper



#a function that accepts a number and returns a function

def accept(f, x):
return f(x)
#returns a function

@adder

@acceptor
def adder(x, y):
# a function that returns the sum of two numbers.
z = x + y
return z




















I guess I will check out the discord, even though I wouldn't be really active.


Thanks in advance.

phazon
Автор

for my code to add two numbers this is what I got, but I got stuck.

def First(fn):
def wrapper(b):
return fn(b) + fn
return wrapper

@First(3)
def adder(b): return b
adder(5)

jaronpirtle
Автор

Nice explanation and examples. I'm learning a lot with your videos
I'm actually failing to see the point of using decorators when you can just compose those functions when you call them and that's more flexible because you can compose what you need each time:
Let's say you already defined your decorator functions then :

def add(a, b): return a + b

Then you compose decorators as you need to get the desired result:
log(round_result(2)(remember(green(add))(a, b)

Or even define some alias to make the code more readable

add_fully_decorated =
add_log = log(add)
add_log_roulded2 = log(round_result(2)(add)
add_remember = remember(add)

Why would you use the @ syntax for decorators when this seems more powerfull to me, or am I missing something?
Can you give us a practical example for when is it better to use @ notation instead of function just composition?

glan-tucan
Автор

My python does not print return results. How do I get it to show return results? is there a reason for this?

jaronpirtle
Автор

Ok...I gave the partial function problem I shot for a little while now, and I'm stuck.








def partial(arg):
def add(func):
def wrapper(x):
return arg + func(x)
return wrapper
return add


@partial(1)
def adder(z):
return z

adder(4)
a = adder(4)

partial(a, 4)(5)










////Previously I tried this






def decorator(func, x):
def wrapper(y):
return func(y) + x
return wrapper


def adder(z):
return z


adder = decorator(adder, 2)










can call the wrapper in both scenarios, but I don't where to proceed. I know partial functions are involved.




I try to remind my self that f = (x)(y)


where x = (add, 1)
y = 3.




.

phazon
Автор

Anyone with the solution to the caching assignment?

emmaose
Автор

i'm too late probably but here is my answer for exercise2


def add(a, b): return a+b




def partial(fn, a):
def wrapper(b):
return fn(a, b)

return wrapper




*and the third is


def make_sum():
a=0
def wrapper(b):
nonlocal a
a=res = a+b
return res
return wrapper

babahs
Автор

Spoiler alert #3












def make_summator():
a=0
def summator(b):
nonlocal a
a=a+b
return a
return summator

summator=make_summator()

summator(1)
summator(4)
...

grzegorzgrzelczyk
join shbcf.ru