Python 我可以使用“function”类创建函数吗?

Python 我可以使用“function”类创建函数吗?,python,python-3.x,Python,Python 3.x,我想知道,只是为了好玩,我是否可以使用函数类构造函数创建函数,即不使用语言构造def,就像通过实例化类型对象创建类一样。我知道,函数构造函数需要2个参数——代码对象和全局变量。但我不知道如何正确编译源代码 >>> def f(): ... pass >>> Function = type(f) >>> Function <class 'function'> >>> code = compile("x

我想知道,只是为了好玩,我是否可以使用函数类构造函数创建函数,即不使用语言构造def,就像通过实例化类型对象创建类一样。我知道,函数构造函数需要2个参数——代码对象和全局变量。但我不知道如何正确编译源代码

>>> def f(): 
...     pass

>>> Function = type(f) 
>>> Function
<class 'function'>
>>> code = compile("x + 10", "<string>", "exec")
>>> f = Function(code, globals())
>>> f()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1, in <module>
NameError: name 'x' is not defined
>>> f(20)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: <module>() takes 0 positional arguments but 1 was given
好吧,这是有效的:

>>> x = 0
>>> def f(): pass
... 
>>> func = type(f)
>>> code = compile("global x\nx += 10","<string>","exec")
>>> nf = func(code,globals())
>>> nf()
>>> x
10
但是,不知道如何将参数传递给函数。

好吧,这是可行的:

>>> x = 0
>>> def f(): pass
... 
>>> func = type(f)
>>> code = compile("global x\nx += 10","<string>","exec")
>>> nf = func(code,globals())
>>> nf()
>>> x
10

但是不知道如何将参数传递给函数。

您需要在代码对象上设置许多属性,例如co_varnames、co_nlocals等。 显然有效的是

code = compile("def foo(n):return n+10", "<string>", "exec").co_consts[0]
func = Function(code, globals())
但我想这会被认为是作弊。要真正从头定义代码对象,请执行3.3

code = types.CodeType(1, 0, 1, 2, 67, b'|\x00\x00d\x01\x00\x17S', (None, 10), 
                      (), ('x',), '<string>', 'f', 1, b'\x00\x01')
func = Function(code, globals())
print(func(10))

当然,这需要您自己完成整个编译。

您需要在代码对象上设置许多属性,例如co_varnames、co_nlocals等。 显然有效的是

code = compile("def foo(n):return n+10", "<string>", "exec").co_consts[0]
func = Function(code, globals())
但我想这会被认为是作弊。要真正从头定义代码对象,请执行3.3

code = types.CodeType(1, 0, 1, 2, 67, b'|\x00\x00d\x01\x00\x17S', (None, 10), 
                      (), ('x',), '<string>', 'f', 1, b'\x00\x01')
func = Function(code, globals())
print(func(10))

当然,这需要您自己完成整个编译。

请注意,它可能需要两个以上的参数。functioncode,globals[,name[,argdefs[,closure]]]你能解释更多吗?我在哪里可以阅读它?导入类型;helptypes.FunctionType请注意,它可以接受两个以上的参数。functioncode,globals[,name[,argdefs[,closure]]]你能解释更多吗?我在哪里可以阅读它?导入类型;helptypes.FunctionTypeGlobals从来都不是解决方案。这也是我所知道的。似乎也不能在代码中放入返回,因为它给出了一个SyntaxError@Tinctorius:是的,这就是关于传递参数的说法。但问题是,人们能否使用函数类构造函数创建函数?。。。这个例子正好说明了这一点。@isedev:不,问题是我应该如何正确编译代码?OP已经在他的帖子中回答了如何创建函数对象的字面问题,指出生成的函数不是真正正确的。全局函数从来都不是解决方案。这也是我所了解的。似乎也不能在代码中放入返回,因为它给出了一个SyntaxError@Tinctorius:是的,这就是关于传递参数的说法。但问题是,人们能否使用函数类构造函数创建函数?。。。这个例子正好说明了这一点。@isedev:不,问题是我应该如何正确编译代码?OP已经在他的帖子中回答了如何创建函数对象的字面问题,指出结果函数并不正确。这是因为compile只返回co_argcount==0的对象吗?@Tintorius:确实如此。编译器仅在进入作用域时提供argcount,这要求它具有参数名和周围作用域的列表。compile只是不提供传递的方法。这是因为compile只返回co_argcount==0的对象吗?@Tinctorius:确实如此。编译器仅在进入作用域时提供argcount,这要求它具有参数名和周围作用域的列表。compile只是不提供传递该信息的方法。