2011-12-10 48 views
3

我可以從python3.2中的全局作用域調用嵌套在另一個函數內部的函數嗎?調用另一個函數中定義的函數

def func1(): 
    def func2(): 
     print("Hello") 
     return 
    return 

是從外部調用func2()func1()的方法嗎?

+1

只有在首先調用func1()時,纔會生成'func2()'對象。爲了解耦這些緊密綁定的'def'語句,我建議總是分別定義每個函數,然後調用'func1()'作爲'func2()'的包裝。 – Droogans

+2

@Sam什麼動機? – eyquem

+0

eyquem的答案有用。它可能不夠優雅或不被推薦,但如果你知道你在做什麼,你可以使用它。比使用dunder屬性/方法等要好得多。 – sureshvv

回答

11

不,除非你返回功能:

def func1(): 
    def func2(): 
     print("Hello") 
    return func2 

innerfunc = func1() 
innerfunc() 

甚至

func1()() 
8

使用@larsmans'的解決方案,但理論上可以削減自己到的代碼對象本地可訪問func1並切出func2的代碼對象並執行:

#!/usr/bin/env python 

def func1(): 
    def func2(): 
     print("Hello") 

# => co_consts is a tuple containing the literals used by the bytecode 
print(func1.__code__.co_consts) 
# => (None, <code object func2 at 0x100430c60, file "/tmp/8457669.py", line 4>) 

exec(func1.__code__.co_consts[1]) 
# => prints 'Hello' 

但是,對於生產代碼,這又是

注意:對於Python 2版本,請使用func_code替換__code__(並從__future__導入print_function)。

一些進一步閱讀:

+3

+1純粹的瘋狂和大膽。雖然不適合代碼需要維護,但很好理解底層發生了什麼(例如,函數與字節碼分離,字節碼可以單獨執行)。 – delnan

+1

@delnan _「很好理解罩下發生的事情」_是的! – eyquem

-1
def func1(): 
    def func2(): 
     global fudu 
     fudu = func2 
     print("Hello") 
    func2() 


func1() 

fudu() 

print 'fudu' in dir() 
print 'func2' in dir() 

結果

Hello 
Hello 
True 
False 

另外:

def func1(): 
    global func2 
    def func2(): 
     print("Hello") 
    func2() 


func1() 

print 'func2' in dir() 
func2() 

結果

Hello 
True 
Hello 

有什麼興趣?

編輯

爲什麼我的答案被低估?

我不認爲我的答案有很大的興趣,但事實是我也想知道這個問題的動機是什麼,我沒有看到任何興趣來解決問題。

+1

我認爲你的答案已被低估的原因是你用很少的解釋放了很多代碼,並且因爲你的代碼有點破解,並且因爲有一個[很好的解決方案](http://stackoverflow.com/ a/8457693/89391)使用功能性編程技術。 –

+0

@Kazark謝謝。由於缺乏解釋,我沒有意識到這種印象。相反,我認爲對於讀者而言,關於如此容易理解的代碼沒有明顯的評論可能會更輕。 - 「黑客」在我看來對我的代碼來說是一個過度的詞 - 我沒有試圖給出比其他代碼更好的答案,我展示了其他可能會給OP帶來額外想法和理解的方式。 – eyquem

+0

好吧,對不起,只是稱它爲黑客;我應該解釋一下。你的代碼在定義時調用了內部函數,這在規範中沒有要求。此外,使用「全球」關鍵字可能會導致一些人對此不滿。 –

0

這是基於eyquem的解決方案。

def func1(): 
    global func2 # put it in global scope 
    def func2(): 
     print("Hello") 

現在你可以直接調用func2了。

但是在調用func2()之前必須調用func1(),否則它將不會被定義。

相關問題