When experiment with python decorators, I got a result that are beyond my understanding, which is related with inner function, closure, assignment.
I try below code,
def myfunc():
print("myfunc")
def decorator1(func):
def inner1(*args, **kwargs):
func(*args, **kwargs)
print("inner1 id = %d " % id(inner1))
# print(inner1.cache)
# return inner1
def decorator2(func):
def inner2(*args, **kwargs):
func(*args, **kwargs)
inner2.cache = {}
print("inner2 id = %d " % id(inner2))
print("\t\t\t cache id = %d " % id(inner2.cache))
return inner2
# Block1 all same
decorator1(myfunc)
decorator1(myfunc)
decorator2(myfunc)
decorator2(myfunc)
decorator1(myfunc)
decorator1(myfunc)
print()
# Block2 deferrent when d2 = ...
decorator1(myfunc)
decorator1(myfunc)
d1 = decorator2(myfunc)
d2 = decorator2(myfunc)
decorator1(myfunc)
decorator1(myfunc)
print()
# Block3 all same
decorator1(myfunc)
decorator1(myfunc)
decorator2(myfunc)
decorator2(myfunc)
decorator1(myfunc)
decorator1(myfunc)
# print()
and get below output
inner1 id = 7696544290000
inner1 id = 7696544290000
inner2 id = 7696544290000
cache id = 7696550302496
inner2 id = 7696544290000
cache id = 7696547474720
inner1 id = 7696544290000
inner1 id = 7696544290000
inner1 id = 7696544290000
inner1 id = 7696544290000
inner2 id = 7696544290000
cache id = 7696550302496
inner2 id = 7696544291152
cache id = 7696547501392
inner1 id = 7696544290144
inner1 id = 7696544290144
inner1 id = 7696544290144
inner1 id = 7696544290144
inner2 id = 7696544290144
cache id = 7696548415040
inner2 id = 7696544290144
cache id = 7696547350000
inner1 id = 7696544290144
inner1 id = 7696544290144
my question is
1 why in Block1, two decorator2 call print same id for inner2, but different id for inner2.cache?
2 why in Block2, inner2 id begin to change, where as in Block1 not? (Block2 assign the returned value, Block1 not.)