2013-03-25 38 views
10

我懷疑是我想做的事情在Python中很乾淨。這裏有幾個互相調用的嵌套函數。 (一般情況下,他們沒有被詞法範圍,但需要動態地稱呼對方。)在Python中調用函數的訪問變量

def outer() : 
    s_outer = "outer\n" 

    def inner() : 
     s_inner = "inner\n" 
     do_something() 

    inner() 

現在,當我打電話do_something()話,我想進一步上漲訪問調用函數中的變量callstack,在這種情況下爲s_outers_inner

不幸的是,這裏的nonlocal關鍵字只有在我定義了inner()函數中的do_something()時纔對我有所幫助。但是,如果我將其定義在與outer()相同的級別,那麼nonlocal關鍵字將不起作用。

但是,我想從各種其他函數調用do_something(),但始終在其各自的上下文中執行它並訪問它們各自的作用域。

感覺調皮然後我寫了一個小訪問,我可以從do_something()這樣的內撥打:

def reach(name) : 
    for f in inspect.stack() : 
     if name in f[0].f_locals : return f[0].f_locals[name] 
    return None 

然後

def do_something() : 
    print(reach("s_outer"), reach("s_inner")) 

的作品就好了。

我的兩個問題是這些

  1. 有沒有更好的辦法來解決這個問題呢? (除包裝各自的數據爲類型的字典,並明確地傳遞這些類型的字典來do_something()

  2. 是否有實現reach()功能更優雅/縮短呢?

乾杯!

回答

1

我最終什麼事做了

scope = locals() 

,並scopedo_something訪問。這種方式我不必到達,但我仍然可以訪問調用者的局部變量字典。這與我自己創建一本字典並傳遞它非常相似。

4

沒有,在我看來,應該沒有實現reach的優雅方法,因爲它引入了一個非常難理解,調試,測試和維護的新的非標準間接方法。正如Python的口頭禪(嘗試import this)所說:

顯式優於隱式。

所以,只要傳遞參數即可。你將來會非常感激你,從今天開始。

+0

我擔心這就是答案。呃,好吧。與reach()函數的作用無關,是否有一種更緊湊的方式來實現嵌套/如果? – Jens 2013-03-25 12:52:11

+0

@Jens不能拿出任何可讀性更強的東西。你可以檢查從'inspect.currentframe()'遍歷'f_back'是否看起來更好。 – bereal 2013-03-25 13:02:23

0

有沒有更好的方法來解決這個問題?(除了將各自的數據封裝在字典中並將這些字典明確地傳遞給do_something())

明確地傳遞字典是一種更好的方法。

你提出的建議聽起來很不合常規。當代碼大小增加時,必須將代碼分解爲模塊化體系結構,並在模塊之間使用乾淨的API。它也必須易於理解,容易解釋,並且易於交給其他程序員修改/改進/調試。你提出的建議聽起來像是而不是一個乾淨的API,非傳統的,具有非明顯的數據流。我懷疑它可能會讓很多程序員在看到它時感到脾氣暴躁。 :)

另一種選擇是使類的函數成員,數據在類實例中。如果您的問題可以建模爲數據對象上運行的幾個函數,那可以很好地工作。

+0

你說的一切都對我有意義,通常我會同意。不過,儘管我現在正在學習Python,這意味着我想盡可能降低和骯髒。這不是運送代碼,只是爲了一個私人項目,所以我會成爲這裏唯一的脾氣暴躁的程序員;-) – Jens 2013-04-08 01:13:01