Estou tendo dificuldades para encontrar uma solução para esse problema. Sempre que decoramos um método de uma classe, o método ainda não está vinculado a nenhuma instância, então digamos que temos:
from functools import wraps
def decorator(f):
closure_variable = 0
@wraps(f)
def wrapper(*args, **kwargs):
nonlocal closure_variable
closure_variable += 1
print(closure_variable)
f(*args, **kwargs)
return
return wrapper
class ClassA:
@decorator
def decorated_method(self):
pass
Isso leva a algo engraçado: todas as instâncias ClassA
estão vinculadas ao mesmo ambiente de fechamento.
inst1 = ClassA()
inst2 = ClassA()
inst3 = ClassA()
inst1.decorated_method()
inst2.decorated_method()
inst3.decorated_method()
As linhas acima produzirão:
1
2
3
Agora, para o meu problema em questão, criei um decorador que armazena em cache um token e só solicita um novo quando ele expira. Este decorador foi aplicado a um método de uma classe chamada TokenSupplier
. Percebi esse comportamento e claramente não quero que isso aconteça. Posso resolver esse problema e manter o padrão de design do decorador aqui?
Pensei em armazenar um dicionário no ambiente de encerramento e usar o hash da instância para indexar os dados desejados, mas acredito que possa estar simplesmente faltando algo mais fundamental. Meu objetivo seria fazer com que cada instância tivesse seu próprio ambiente de fechamento, mas ainda pudesse usar um padrão decorador para decorar diferentes TokenSupplier
implementações futuras.
Agradeço antecipadamente!
Para evitar o compartilhamento do cache entre todas as instâncias, o que pode não ser obrigatório ou desejado, é melhor ter um cache para cada instância com prazo de validade, etc. cache" para todas as instâncias.
Na implementação a seguir, cada instância de uma classe inicializa seu próprio cache
dict()
para armazenar o token, seu tempo de expiração e outras informações relevantes, que lhe darão controle total.Impressões