phileas fogg
phileas fogg

Reputation: 1933

Why isn't this variable visible?

O.K., I'm coming from Perl to Python and I don't have much experience in Python so this may seem rather obvious to everyone who's more experienced with Python.

Anyway, I'm simply loading a configuration file and then, as a self-test, printing the values that are loaded. The code is below:

#!/home/y/bin/python2.7
import logging
import sys
import datetime
import yaml

def main(self):
    #initialize the logger
    logger = logging.getLogger(self.granularity)
    log_fh = logging.FileHandler(filename='/home/logs/pipelineTest/pipelineTest' + datetime.datetime.now().strftime('%Y%m%d_%H%M')  + '.log', mode='w')
    logger.addHandler(log_fh)
    logger.setLevel(logging.INFO)
    formatter = logging.Formatter('%(asctime)-6s: %(name)s - %(levelname)s - %(message)s')
    log_fh.setFormatter(formatter)

    #read configuration file
    if sys.argv[1]:
        ymlFH = open(sys.argv[1])
    else:
        ymFH = open('/home/conf/pipelineTest/runPipeline.yml')

    confDict = yaml.load(ymlFH)

if __name__ == '__main__':
    #self-test code
    for key, value in confDict.iteritems():
      print 'Key is: ' + key + '\n'
      print 'value is: ' + confDict[key] + '\n'

The error I'm encountering is:

Traceback (most recent call last):
  File "./runPipeline.py", line 30, in <module>
    for key, value in confDict.iteritems():
NameError: name 'confDict' is not defined

Which I'm interpreting as the name "confDict" has gone out of scope. I don't understand why it's gone out of scope.

Upvotes: 0

Views: 168

Answers (4)

Ben
Ben

Reputation: 71495

It's not that confDict went out of scope, it never went into scope.

import ...

def main(self):
    ...

if __name__ == '__main__':
    #self-test code
    for key, value in confDict.iteritems():
      print 'Key is: ' + key + '\n'
      print 'value is: ' + confDict[key] + '\n'

At the point of that if __name__ == ..., you have imported a bunch of names, and defined a function called main. The variable condDict has never been defined. I do not know of any language where analogous code would define condDict, regardless of what is filling in the ... in main.

If you call main, it will create a variable called confDict. However that name will be local to that particular invocation of main, so you can't use it outside the function meaningfully (imagine you could; main could be called many times, and produce many values of confDict; which one would be meant when you refer to confDict outside main?).

I suggest you work through some Python tutorials. If you're already familiar with programming in general (i.e. Perl) then you'll blaze through them, but they'll clarify all these basic foundational issues so you can concentrate on coding.


As an aside, self as the argument to main makes no sense. Either remove it and have def main(): or use def main(args) instead of pulling them out of sys.argv within main (my preference is for the latter).

Upvotes: 0

Gareth Latty
Gareth Latty

Reputation: 89017

Your main() function has it's own scope - not only that, but you are never calling it.

I would suggest you return confDict from your function, and then do confDict = main() in your running block - or, if you are not going to use your main() function in more than one place, just put it straight down, don't bother with the function.

Upvotes: 6

ppsreejith
ppsreejith

Reputation: 3438

confDict is local to main, and in python, function defenitions are indent dependant. So the function scope is over when you try to access it inside the if statement because main has already ended. (See indent)

Upvotes: 0

Sven Marnach
Sven Marnach

Reputation: 601779

The variable confDict is defined inside the function main(), so it is local to that function. (By the way, you don't even call main().)

You probably want to move the for loop from the end of the script to the end of the main() function, and call main() at the end of the script instead.

Upvotes: 4

Related Questions