Pytorch: Why does evaluating a string (of an optimizer) in a function break the function?
I have a pytorch lightning class that looks like this:
import torch.optim as optim

class GraphLevelGNN(pl.LightningModule):

def __init__(self,**model_kwargs):
    super().__init__()


    self.save_hyperparameters()
    self.model = GraphGNNModel(**model_kwargs)
    self.loss_module = nn.BCEWithLogitsLoss()
    self.optimizer = eval('optim.SGD(self.parameters(),lr=0.1)')

def forward(self, data, mode=&quot;train&quot;):
    x, edge_index, batch_idx = data.x, data.edge_index, data.batch
    x = self.model(x, edge_index, batch_idx)
    x = x.squeeze(dim=-1)
    
    if self.hparams.c_out == 1:
        preds = (x &gt; 0).float()
        data.y = data.y.float()
    else:
        preds = x.argmax(dim=-1)

    loss = self.loss_module(x, data.y)
    acc = (preds == data.y).sum().float() / preds.shape[0]

    return loss, acc,preds

def configure_optimizers(self):
    optimizer = self.optimizer
    return optimizer

def training_step(self, batch, batch_idx):
    loss, acc _ = self.forward(batch, mode=&quot;train&quot;)
    self.log('train_loss', loss,on_epoch=True,logger=True,batch_size=64)
    self.log('train_acc', acc,on_epoch=True,logger=True,batch_size=64)


def validation_step(self, batch, batch_idx):
    loss, acc,_ = self.forward(batch, mode=&quot;val&quot;)
    self.log('val_acc', acc,on_epoch=True,logger=True,batch_size=64)
    self.log('val_loss', loss,on_epoch=True,logger=True,batch_size=64)

def test_step(self, batch, batch_idx):
    loss,acc, preds = self.forward(batch, mode=&quot;test&quot;)
    self.log('test_acc', acc,on_epoch=True,logger=True,batch_size=64)

I eventually want to put the optimizer into a ray tune object, so I want it to not be hard coded in this function.
Why is it that when I have:
 self.optimizer = optim.SGD(self.parameters(),lr=0.1)

in the __init__ part, the script works, but when I change to eval('optim.SGD(self.parameters(),lr=0.1)'), then the function breaks with the error:
  File &quot;script.py&quot;, line 560, in __init__
    self.optimizer = eval('optim.SGD(self.parameters(),lr=0.1)')
  File &quot;&lt;string&gt;&quot;, line 1, in &lt;module&gt;
NameError: name 'optim' is not defined

I also tried changing optim to torch.optim but it produces the same error.
Should the eval not change the string 'optim.SGD(self.parameters(),lr=0.1)' to optim.SGD(self.parameters(),lr=0.1)

Even though using eval is not the correct approach to your problem, let me just explain why you are facing this error.
The python function eval does not import any modules or functions in the script you are running by default.
For example, you can take eval as the python interpreter, when you just open the interpreter, and do not import any modules or write any functions, it will give you an error when you try and use them. Like if you use time.sleep() function without importing time, it gives you an error.
To overcome this, it allows you to assign variables in the arguments of the eval function.
eval(expression[, globals[, locals]])

You can read about it here -
https://docs.python.org/3/library/functions.html#eval
https://www.programiz.com/python-programming/methods/built-in/eval
