2013-08-19 31 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?