如何在模块中动态创建 python 函数?
How to dynamically create a python function within a module?
我写了一个函数 def_function
,它在运行时动态定义了另一个函数。
main.py
#!/usr/bin/python3
def def_function(name):
lines = list()
lines.append('global {}\n'.format(name))
lines.append('def {}():\n'.format(name))
lines.append(' print(\'{}() has been called!\')\n'.format(name))
code = ''.join(lines)
function = compile(code, '', 'exec')
exec(function)
def_function('foo')
foo()
运行 main.py 给出了预期的输出:
foo() has been called!
现在我想将 def_function
的定义移动到 module.py
并从 main.py
导入它。
module.py
def def_function(name):
lines = list()
lines.append('global {}\n'.format(name))
lines.append('def {}():\n'.format(name))
lines.append(' print(\'{}() has been called!\')\n'.format(name))
code = ''.join(lines)
function = compile(code, '', 'exec')
exec(function)
main.py
#!/usr/bin/python3
from module import def_function
def_function('foo')
foo()
这会导致以下错误:
Traceback (most recent call last):
File "./main.py", line 6, in <module>
foo()
NameError: name 'foo' is not defined
我已经用谷歌搜索了我的问题并阅读了 SO 上的各种问题,但找不到解决方案。请帮助我。
您在 module.py
范围内定义 foo
。不要忘记导入 module.py
.
调用 foo()
,作为 module.foo()
。
import module
module.def_function('foo')
module.foo()
可能对你有帮助https://realpython.com/python-scope-legb-rule/
额外
在 exec(function)
之后添加这个。同时导入 sys
.
setattr(sys.modules['__main__'], name, globals()[name])
Setattr 它的功能是将值分配给对象的属性或创建新的属性。
https://docs.python.org/3/library/functions.html#setattr
module.py
import sys
def def_function(name):
lines = list()
lines.append('global {}\n'.format(name))
lines.append('def {}():\n'.format(name))
lines.append(' print(\'{}() has been called!\')\n'.format(name))
code = ''.join(lines)
function = compile(code, '', 'exec')
exec(function)
setattr(sys.modules['__main__'], name, globals()[name])
main.py
from module import def_function
def_function('foo')
foo()
你的例子可以这样写,有一个嵌套的函数定义,没有compile
或exec
:
def def_function(name):
def f():
print(name, "has been called")
return f
# ...
foo = def_function("foo")
但是,您必须 return 它。
我写了一个函数 def_function
,它在运行时动态定义了另一个函数。
main.py
#!/usr/bin/python3
def def_function(name):
lines = list()
lines.append('global {}\n'.format(name))
lines.append('def {}():\n'.format(name))
lines.append(' print(\'{}() has been called!\')\n'.format(name))
code = ''.join(lines)
function = compile(code, '', 'exec')
exec(function)
def_function('foo')
foo()
运行 main.py 给出了预期的输出:
foo() has been called!
现在我想将 def_function
的定义移动到 module.py
并从 main.py
导入它。
module.py
def def_function(name):
lines = list()
lines.append('global {}\n'.format(name))
lines.append('def {}():\n'.format(name))
lines.append(' print(\'{}() has been called!\')\n'.format(name))
code = ''.join(lines)
function = compile(code, '', 'exec')
exec(function)
main.py
#!/usr/bin/python3
from module import def_function
def_function('foo')
foo()
这会导致以下错误:
Traceback (most recent call last):
File "./main.py", line 6, in <module>
foo()
NameError: name 'foo' is not defined
我已经用谷歌搜索了我的问题并阅读了 SO 上的各种问题,但找不到解决方案。请帮助我。
您在 module.py
范围内定义 foo
。不要忘记导入 module.py
.
调用 foo()
,作为 module.foo()
。
import module
module.def_function('foo')
module.foo()
可能对你有帮助https://realpython.com/python-scope-legb-rule/
额外
在 exec(function)
之后添加这个。同时导入 sys
.
setattr(sys.modules['__main__'], name, globals()[name])
Setattr 它的功能是将值分配给对象的属性或创建新的属性。 https://docs.python.org/3/library/functions.html#setattr
module.py
import sys
def def_function(name):
lines = list()
lines.append('global {}\n'.format(name))
lines.append('def {}():\n'.format(name))
lines.append(' print(\'{}() has been called!\')\n'.format(name))
code = ''.join(lines)
function = compile(code, '', 'exec')
exec(function)
setattr(sys.modules['__main__'], name, globals()[name])
main.py
from module import def_function
def_function('foo')
foo()
你的例子可以这样写,有一个嵌套的函数定义,没有compile
或exec
:
def def_function(name):
def f():
print(name, "has been called")
return f
# ...
foo = def_function("foo")
但是,您必须 return 它。