Obtendo o bloco de comandos que devem ser executados na instrução with
Ao ler as especificações para owith
declaração (ligaçãoEu tenho algumas coisas com as quais gostaria de brincar. Isso não é para nenhum código de produção ou nada, estou apenas explorando, então, por favor, não seja muito duro se isso for uma má idéia.
O que eu gostaria de fazer é pegar a peça chamada "BLOCK" nos documentos relacionados acima, e realmente mexer com ela dentro da chamada para__enter__
. (Veja o documento relacionado, logo após o início da seção de motivação e resumo.)
A ideia é criar meu próprio namespace local on-the-fly. Algo assim:
with MyNameSpace(some_object):
print a #Should print some_object.a
x = 4 #Should set some_object.x=4
Basicamente, eu quero as declarações dentro dowith
bloco para ser subordinado às variáveis locais e convenções de atribuição desome_object
.
No meu caso específico,some_object
pode ser uma matriz de dados especial que tenha minhas próprias operações de coluna ou algo assim. Nesse caso, dizendo algo comox = y + 5 if y > 4 else y - 2
pode ser alguma operação vetorizada NumPy fantasia sob o capô, mas eu não preciso chamar explicitamentesome_object
interface para esses métodos. No espaço de nomes, as expressões devem "apenas funcionar" (no entanto, defino-as como inferidas noMyNameSpace
classe.
Minha primeira idéia é de alguma forma interromper owith
processar e se apossar do código que vai notry
quadra. Então interprete esse código quando__enter__
é chamado e substitua o código notry
bloquear com outra coisa (talvezpass
se isso funcionasse, mas possivelmente algo que restaurasome_object
de volta ao escopo da variável original com suas novas variáveis alteradas preservadas).
Um caso de teste simples seria algo assim:
my_dict = {'a':3, 'b':2}
with MyNameSpace(my_dict):
print a # Should print 3
x = 5 # When the block finishes, my_dict['x'] should now be 5
Estou interessado se essa ideia já existe em algum lugar.
Estou ciente das melhores práticas para atribuir variáveis. Este é um projeto de estimação, por isso, suponha que, apenas por causa desta ideia, podemos ignorar as melhores práticas. Mesmo que você não queira atribuir variáveis dessa maneira, isso pode ser útil no meu projeto atual.
Editar
Para esclarecer os tipos de coisas complicadas que eu gostaria de fazer e responder à resposta abaixo, alegando que isso não pode ser feito, considere o arquivo de exemplotestLocals.py
abaixo:
my_dict = {'a':1, 'b':2}
m = locals()
print m["my_dict"]['a']
m["my_dict"]['c'] = 3
print my_dict
class some_other_scope(object):
def __init__(self, some_scope):
x = 5
g = locals()
some_scope.update(g)
some_scope["my_dict"]["d"] = 4
sos = some_other_scope(m)
print my_dict
print x
que dá o seguinte quando eu o executo de forma não interativa:
ely@AMDESK:~/Desktop/Programming/Python$ python testLocals.py
1
{'a': 1, 'c': 3, 'b': 2}
{'a': 1, 'c': 3, 'b': 2, 'd': 4}
5