O loop for não funciona dentro de uma função python
Tento criar uma função com um loop para dentro. O script funciona sem função, mas declara que a função python não funciona. (O roteiro original é mais longo, mas com essa parte acho que é o suficiente)
import numpy as np
import math as mt
from sympy import*
import fractions
init_printing(use_latex='mathjax')
PHnumbers=4
PHnumbers2=2
statetype= 1
for d in range(1,9):
modes=d+1
if statetype==1:
comb=modes
elif statetype==2:
comb=int((modes*(modes+1))/2)
exec(f'Phases{d}=[]'), exec(f'Phasesv{d}=[]')
for i in range(modes):
exec(f'theta_{i+1}= symbols(\'theta_{i+1}\', real=True)')
exec(f'Phases{d}.append(globals()[\'\'.join([\'theta_\',str(i+1)])])')
exec(f'Phasesv{d}.append(globals()[\'\'.join([\'theta_\',str(i+1)])])')
exec(f'v{i+1}=[[0]]*modes')
exec(f'Phasesv{d}[0]*=0')
for i in range(modes):
exec(f'globals()[\'\'.join([\'v\',str(i+1)])][i]=[PHnumbers*diff(Phasesv{d}[i],Phases{d}[i])]')
conteo = d
for j in range(modes):
for i in range(modes):
if j<i:
conteo = conteo + 1
exec(f'v{conteo+1}=[[0]]*modes')
exec(f'globals()[\'\'.join([\'v\',str(conteo+1)])][i]=[PHnumbers2*diff(Phasesv{d}[i],Phases{d}[i])]')
exec(f'globals()[\'\'.join([\'v\',str(conteo+1)])][j]=[PHnumbers2*diff(Phasesv{d}[j],Phases{d}[j])]')
exec(f'Vec{d}=[]'),exec(f'Coeff{d}=[]'), exec(f'Nii{d}=[]'), exec(f'Nij{d}=[]')
for i in range(comb):
exec(f'Vec{d}.append(globals()[\'\'.join([\'v\',str(i+1)])])')
for i in range (len (Vec4)): print (Vec4 [i]) O script anterior funcionou, sem problemas até aqui. Agora declaro a função python:
def metro(PHnumbers):
statetype=1
PHnumbers2=2
for d in range(1,9):
modes=d+1
if statetype==1:
comb=modes
elif statetype==2:
comb=int((modes*(modes+1))/2)
exec(f'Phases{d}=[]'), exec(f'Phasesv{d}=[]')
for i in range(modes):
exec(f'theta_{i+1}= symbols(\'theta_{i+1}\', real=True)')
exec(f'Phases{d}.append(globals()[\'\'.join([\'theta_\',str(i+1)])])')
exec(f'Phasesv{d}.append(globals()[\'\'.join([\'theta_\',str(i+1)])])')
exec(f'v{i+1}=[[0]]*modes')
exec(f'Phasesv{d}[0]*=0')
for i in range(modes):
exec(f'globals()[\'\'.join([\'v\',str(i+1)])][i]=[PHnumbers*diff(Phasesv{d}[i],Phases{d}[i])]')
conteo = d
for j in range(modes):
for i in range(modes):
if j<i:
conteo = conteo + 1
exec(f'v{conteo+1}=[[0]]*modes')
exec(f'globals()[\'\'.join([\'v\',str(conteo+1)])][i]=[PHnumbers2*diff(Phasesv{d}[i],Phases{d}[i])]')
exec(f'globals()[\'\'.join([\'v\',str(conteo+1)])][j]=[PHnumbers2*diff(Phasesv{d}[j],Phases{d}[j])]')
exec(f'Vec{d}=[]'),exec(f'Coeff{d}=[]'), exec(f'Nii{d}=[]'), exec(f'Nij{d}=[]')
for i in range(comb):
exec(f'Vec{d}.append(globals()[\'\'.join([\'v\',str(i+1)])])')
for i in range(len(Vec4)):
print(Vec4[i])
O segundo código mostra o problema: 'theta_1 is not defined'
Respostas
Da documentação paraexec :
Nota : Os locais padrão agem conforme descrito para a função locals () abaixo: modificações no dicionário de locais padrão não devem ser tentadas. Passe um dicionário de locais explícito se você precisar ver os efeitos do código nos locais após o retorno da função exec ().
Então, em essência, você não pode execmexer com variáveis locais, por razões de eficiência do intérprete. A mesma restrição não se aplica a globais, e é por isso que sua primeira versão funciona.
Quanto ao que fazer: bem, as execligações são altamente desnecessárias. Simplesmente execute o código Python normalmente, sem as execchamadas confusas . Sinceramente, provavelmente será mais rápido também. Em todos os lugares onde você hackear classes de variáveis com nomes semelhantes, apenas substitua-as por um único array ou dicionário, dependendo do caso de uso.
Parece que pode ser um erro de recuo.
Sua primeira amostra é
for d in range(1,9):
modes=d+1
if statetype==1:
enquanto sua nova definição é
for d in range(1,9):
modes=d+1
if statetype==1:
em torno da linha 4