2013-08-19 32 views
0

如果问题非常愚蠢,请亲自留下,但我基本上来自c/C++背景。python访问方法中的全局变量。

我有以下代码。

#!/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); 

问:

如何logMsg()FileLogger类的函数可以访问logHandler?

我可以认为'logHandler'是一个全局变量吗?

+0

简短的回答是:是的,你可以考虑'logHandler'为全局变量;这正是它的原因。它会让你的代码更加清晰,并且对将来的读者来说,将'global logHandler'添加到'logMsg'函数定义的顶部,但在这种情况下并不是必须的。 – abarnert

回答

1

请参阅Naming and Binding参考;未在函数中分配给('绑定')的函数中的Python名称被认为是自由变量

如果变量在一个码块使用,但没有定义,它是一个自由变量

自由变量在父范围内查找,最终在全局范围内查找。

logHandler名称永远不会分配给logMsg()函数,因此Python认为它是一个自由变量并在全局名称空间中查找它。在你的模块中有一个实际的全局名称,所以代码可以工作,并且不会抛出异常。

给了函数本地名称log,即通过logHandler对象;函数log内部绑定为相同对象,所以你可以用log.logMsg()代替。

+0

Martijn,我害怕,我听不懂。你能否提供更多的信息? – Whoami

+0

@Whoami:'self'是指在*上调用该方法的对象。它指的是当你调用'logHandler.logMsg()'时'logHandler'绑定的同一个对象。 –

+0

我明白了,self只不过是C++中的一个指针,但我的正式pameter是'log',但是如何访问logHandler呢? – Whoami

2

当你在任何函数外部定义logHandler变量时,该变量在模块内(本质上是Python文件)在范围内变为全局变量,你可以在像logMsg(log)这样的函数内看到它(并引用它)。

但是,在您编写的代码的上下文中,在我看来,使用logHandler这种方式会是一个错误,因为您将logHandler对象传递给logMsg函数。你logMsg功能应该是这样的,我会想:

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

否则,当你通过不同的物体插入功能,将试图访问哪一个是在全局变量logHandler,而不是一个你传入日志。

这个其他问题的答案提供了更详细的有关Python作用域:

Short Description of the Scoping Rules?