Search code examples
pythonspyder

Spyder - NameError: name 'variable' is not defined with vars(), but gobals works


I am creating dynamic variables with:

import mplfinance as mpf
import pandas as pd
from polygon import RESTClient

def main():
    with RESTClient('key') as client:
        start = "2019-02-01"
        end = "2019-02-02"
        ticker = "TVIX"
        intervals = [5,15,30,60]
        
        for i in intervals:
            print(f'downloading {i} minutes.')
            vars()[f'df{i}'] = client.stocks_equities_aggregates(ticker, str(i), "minute", start, end, unadjusted=False)
                       
        print(df5)

if __name__ == '__main__':
    main()

When running I get the error NameError: name 'df5' is not defined.

I can debug and see the variable does exist under Spyder variable explorer as below.

enter image description here

It works for global() but not vars() what am I doing wrong please?


Solution

  • I've done some testing with a simplified version of your code. After some searching online it's not clear to me where you got that idea that you can create a new variable by simply adding an entry to the locals() dict. It does appear to work when adding to the globals() dict:

    import pprint
    
    def main():
    
        pp = pprint.PrettyPrinter(indent=4)
    
        intervals = [5,15,30,60]
    
        for i in intervals:
            print(f'i = {i}')
            vars()[f'df{i}'] = i**3
            # if i == 5:
            #    print('i==5: df5=',df5)
            globals()[f'df{i}'] = i**3
            if i == 5:
                print('i==5: df5=',df5)
    
        print('vars()=')
        pp.pprint(vars())
    
        print('globals()=')
        pp.pprint(globals())
    
        print('df5=')
        print(df5)
    
    if __name__ == '__main__':
        main()
    

    If you run the above code, it works. But if you uncomment the lines:

            if i == 5:
               print('i==5: df5=',df5)
    

    You will see that even in the namespace of the loop, the variable df5 is not defined. Apparently this idiom of dynamically creating a new symbolic name with locals() does not work.