0

Kindly bare if the question is so silly, but i am basically from c/c++ background.

I have the following code.

#!/usr/bin/python

import os


class Logger(object):

    def __init__ (self):
        print "Constructor of Logger "

    def logMsg(self):
        print "logMsg::"


class FileLogger (Logger):
    def __init__ (self):
        print "Constructor of File Logger"
    def logMsg (self):
        print "FileLogger::"

class FTPLogger (Logger):

    def __init__ (self):
        print "Constructor of FTP Logger"

    def logMsg (self):
        print "FTPLogger::"


def logMsg(log):
    print "Logging Message"
    logHandler.logMsg()    # **HERE: HOW POSSIBLE TO ACCESS logHandler Variable?**


logHandler = FileLogger ();
logMsg(logHandler);

Question:

How logMsg() function of FileLogger class be able to access logHandler?.

Can i consider 'logHandler'is a global variable?

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
Whoami
  • 13,930
  • 19
  • 84
  • 140
  • The short answer is: Yes, you can consider `logHandler` as a global variable; that's exactly what it is. It would make your code a whole lot clearer to you, and to future readers, to add `global logHandler` to the top of the `logMsg` function definition, but in this case it's not necessary. – abarnert Aug 19 '13 at 21:20

2 Answers2

2

When you define the logHandler variable outside any function, that variable becomes global in scope within the module (essentially the Python file) and you can see it (and refer to it) inside a function like logMsg(log).

However, in the context of the code you've written, it seems to me like using logHandler that way would be a mistake, since you're passing the logHandler object into the logMsg function. Your logMsg function should look like this, I would think:

def logMsg(log):
    print "Logging Message"
    log.logMsg()

Otherwise, when you pass a different object into the function, it will be trying to access whichever one is in the global variable logHandler and not the one you passed in in log.

The answers to this other question provide more detail about Python scoping:

Short Description of the Scoping Rules?

Community
  • 1
  • 1
Mark R. Wilkins
  • 1,282
  • 7
  • 15
1

See the Naming and Binding reference; Python names in functions that are not assigned to ('bound') in that function, are considered free variables.

If a variable is used in a code block but not defined there, it is a free variable.

Free variables are looked up in parent scopes, ultimately in the global scope.

The logHandler name is never assigned to in the logMsg() function, so Python considers it a free variable and looks it up in the global namespace. There is an actual global in your module by that name, so the code works and does not throw a NameError exception.

You also gave the function a local name log, that is passed the logHandler object; inside the function log is bound to the same object, so you could have used log.logMsg() instead.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • Martijn, i am afraid, i could not understand. Could you kindly provide bit more information? – Whoami Aug 19 '13 at 19:08
  • @Whoami: `self` refers to the object the method was called *on*. It refers to the same object that `logHandler` is bound to when you call `logHandler.logMsg()`. – Martijn Pieters Aug 19 '13 at 19:12
  • i understood, self is nothing but a this pointer in c++, but my formal pameter is 'log', but how that is possible to access logHandler then?. – Whoami Aug 19 '13 at 19:21
  • @Whoami: I think I misunderstood your question. Python automatically marks *any* name in a function that is not local (being assigned to) as a global instead. `logHandler` is not assigned to in the function, so it is a global; if you did *not* have `logHandler` defined at the top level of your module a `NameError` exception would be thrown. – Martijn Pieters Aug 19 '13 at 19:24