簡體   English   中英

function的code object使用Python exec如何獲取返回值?

[英]How do I get the return value when using Python exec on the code object of a function?

出於測試目的,我想直接執行在另一個 function 內部定義的 function。

我可以通過父 function 的代碼(func_code)獲取子 function 的代碼 object,但是當我執行它時,我沒有返回值。

有沒有辦法從執行代碼中獲取返回值?

是的,您需要在exec語句中進行賦值:

>>> def foo():
...     return 5
...
>>> exec("a = foo()")
>>> a
5

這可能與您的情況無關,因為它用於受控測試,但在使用exec和用戶定義的輸入時要小心。

幾年后,但以下片段幫助了我:

the_code = '''
a = 1
b = 2
return_me = a + b
'''

loc = {}
exec(the_code, globals(), loc)
return_workaround = loc['return_me']
print(return_workaround)  # 3

exec()本身不返回任何內容,但您可以傳遞一個dict ,其中在執行后存儲了所有局部變量。 通過訪問它,您可以獲得類似回報的東西

我希望它可以幫助某人。

雖然這是人類見過的最丑陋的野獸,但您可以通過在 exec 調用中使用全局變量來做到這一點:

def my_exec(code):
    exec('global i; i = %s' % code)
    global i
    return i

這是濫用全局變量來跨越邊界獲取數據。

>>> my_exec('1 + 2')
3

毋庸置疑,您永遠不應該允許任何用戶輸入用於此功能的輸入,因為它會帶來極大的安全風險。

這樣的事情可以工作:

def outer():
    def inner(i):
        return i + 10


for f in outer.func_code.co_consts:
    if getattr(f, 'co_name', None) == 'inner':

        inner = type(outer)(f, globals())

        # can also use `types` module for readability:
        # inner = types.FunctionType(f, globals())

        print inner(42) # 52

這個想法是從內部函數中提取代碼對象並基於它創建一個新函數。

當內部函數可以包含自由變量時,需要額外的工作。 您還必須提取它們並傳遞給最后一個參數( closure )中的函數構造函數。

這是一種從 exec 代碼返回值的方法:

def exec_and_return(expression):
    exec(f"""locals()['temp'] = {expression}""")
    return locals()['temp']

我建議你舉一個你試圖解決的問題的例子。 因為我只會把它作為最后的手段。

這不會得到每個說的返回值,但是在調用exec以檢索代碼中定義的任何變量時,您可以提供一個空字典。

# Python 3
ex_locals = {}
exec("a = 'Hello world!'", None, ex_locals)
print(ex_locals['a'])
# Output: Hello world!

來自exec 上Python 3 文檔

默認 locals 的行為如下面的函數locals()所述:不應嘗試修改默認 locals 字典。 如果您需要在函數exec()返回后查看代碼對局部變量的影響,請傳遞一個顯式局部變量字典。

有關更多信息,請參閱exec 如何與本地人一起工作?

這是一個帶有簡單代碼的解決方案:

# -*- coding: utf-8 -*-
import math

x = [0]
exec("x[0] = 3*2")
print(x[0]) # 6

從 Python 3.7 開始,字典是有序的。 因此,您不再需要就名稱達成一致,您只需說“最后創建的項目”:

>>> d = {}
>>> exec("def addone(i): return i + 1", d, d)
>>> list(d)
['__builtins__', 'addone']
>>> thefunction = d[list(d)[-1]]
>>> thefunction
<function addone at 0x7fd03123fe50>

使用eval()而不是exec() ,它返回結果

如果我們需要一個位於另一個目錄中的文件中的函數,例如
我們需要在文件my_py_file.py期函數
位於/home/.../another_directory
我們可以使用以下代碼:

def cl_import_function(a_func,py_file,in_Dir):
... 導入系統
... sys.path.insert(0, in_Dir)
... ax='from %s import %s'%(py_file,a_func)
... loc={}
... exec(ax, globals(), loc)
... getFx = loc[afunc]
...返回getFx

test = cl_import_function('function1',r'my_py_file',r'/home/.../another_directory/')

測試()
(新手的簡單方法...)

program = 'a = 5\nb=10\nprint("Sum =", a + b)'

program = exec(program)

print(program)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM