Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/293.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:如何将参数传递给函数的_代码_?_Python_Function_Parameter Passing_Exec_Eval - Fatal编程技术网

Python:如何将参数传递给函数的_代码_?

Python:如何将参数传递给函数的_代码_?,python,function,parameter-passing,exec,eval,Python,Function,Parameter Passing,Exec,Eval,以下工作: def spam(): print "spam" exec(spam.__code__) 垃圾邮件 但是如果垃圾邮件包含参数怎么办 def spam(eggs): print "spam and", eggs exec(spam.__code__) TypeError:spam()正好接受1个参数(给定0) 假设我不能访问函数本身,只能访问代码对象,那么在执行代码对象时,如何将参数传递给代码对象?用eval可以吗 编辑:由于大多数读者倾向于不相信这一点的有用性,请

以下工作:

def spam():
    print "spam"
exec(spam.__code__)
垃圾邮件

但是如果垃圾邮件包含参数怎么办

def spam(eggs):
    print "spam and", eggs
exec(spam.__code__)
TypeError:spam()正好接受1个参数(给定0)

假设我不能访问函数本身,只能访问代码对象,那么在执行代码对象时,如何将参数传递给代码对象?用eval可以吗

编辑:由于大多数读者倾向于不相信这一点的有用性,请参见以下用例:

我想将小型Python函数保存到一个文件中,以便可以从另一台计算机调用它们。(这里不用说,这个用例严重限制了可能的函数。)pickle函数对象本身无法工作,因为这只保存名称和定义函数的模块。相反,我可以对函数的
\uuuuuuuuuuuu
进行pickle。当我再次取消勾选它时,对该函数的引用当然消失了,这就是为什么我不能调用该函数的原因。我只是在运行时没有它

另一个用例:

我在一个文件中处理几个函数,计算一些数据并将其存储在硬盘上。计算会消耗大量时间,因此我不希望每次都执行函数,而只希望在函数的实现发生更改时执行


我有一个版本的这个运行整个模块,而不是一个函数。它通过查看模块在其中实现的文件的修改时间来工作。但是,如果我有许多不想在单个文件中分离的函数,那么这不是一个选项。

能否将函数更改为不带任何参数?然后从局部变量/全局变量中查找变量,您可以将变量提供到
exec

>>> def spam():
...   print "spam and", eggs
... 
>>> exec(spam.__code__, {'eggs':'pasta'})
spam and pasta

(为什么不将整个函数作为字符串发送呢?Pickle
“def spam(eggs):打印'spam and',eggs'
,并在另一端打印字符串(验证后)。

我认为不能将参数传递给
exec
eval
,以便将它们传递给代码对象

您可以使用exec/eval的字符串版本,例如
exec(“垃圾邮件(3)”)

您可以创建另一个绑定参数的代码对象,然后执行以下操作:

def spam_with_eggs():
   return spam(3)
exec(spam_with_eggs.__code__)
(我原以为你也可以用
functools.partial
实现这一点,但没有成功)

编辑:

在阅读了您的其他解释之后,我想到了从code对象重新建立适当函数的方法。这个简单的方法对我很有效(在python2.5中):


我完全反对使用这种代码。

虽然我是一个好奇的人,理论上有人会这么做:

code # This is your code object that you want to execute

def new_func(eggs): pass
new_func.__code__ = code
new_func('eggs')

再说一次,我永远都不想看到这个被使用。如果您想在运行时加载代码,您可能需要查看
\uuuuuu import\uuuuuu

我认为在您的大型应用程序中可能存在一些设计考虑因素,使您不必关心此问题,例如,可能有一些“已知良好且有效”的函数集合作为执行代理知道的模块分发

也就是说,一个黑客解决方案是:

>>> def spam(eggs):
...     print "spam and %s" % eggs
...     
... 
>>> spam('bacon')
spam and bacon
>>> def util():
...     pass
...     
... 
>>> util.__code__ = spam.__code__
>>> util('bacon')
spam and bacon
>>> 

我的方法,我觉得它更漂亮

def f(x):
    print(x, x+1)

g = type(f)(f.__code__, globals(), "optional_name")

g(3)

代码对象是函数的一部分,因此上面的几个答案建议创建一个伪函数,并用
代码对象
替换它的
。下面是另一种避免制作和丢弃新的
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
的方法:

import new
newFunction = new.function(codeObject, globals())

(在Python 2.7中测试,其中
spam.\uu code\uu
被命名为
spam.func\u code

只需调用函数period,full stop。当然,在这个简单的示例中我会这样做。我没那么傻,没看到这个。但是如果我所拥有的只是代码对象本身呢?那么我会说,你有一个更严重的问题。您很少(真的很少)需要处理这个抽象级别的东西,默认情况下,我怀疑您的情况是这样的,所以我建议您确保获得的是函数而不是代码对象。@Turion:函数和代码对象本身有什么区别?你从哪里得到这个代码对象的?为什么它不只是一个函数呢?那么您希望通过网络发送pickle函数字节码,并且希望客户端能够允许从任意位置执行代码?哇。这在很多方面都很危险。。。您需要的是某种形式的RPC。不要抄近路。我也喜欢这个解决方案,但不幸的是,我认为我只能选择其中一个解决方案。但是我同意,这真的很难。你也可以用函数类型构造一个函数。e、 g.
new_func=type(lambda:0)(code,globals())
这有点不太老套。然后,您可以编写一个函数,从代码对象构造一个包装器函数,并调用生成的函数。这是一个改进。为了提高解决方案的可读性,我建议使用
types.FunctionType
而不是
type(lambda:0)
。我喜欢这样,就像Gustav Larssons解决方案一样。这与其他一些解决方案没有显著区别。这非常有趣,更准确地说,您还可以提供默认参数以防万一。将此作为关键字参数添加到构造函数
argdefs=f.\uuuu默认值\uuuuu
这应该被标记为最正确的答案,尽管另一个答案中的注释仍然使用该奇怪的hack通过
types.FunctionType
提到了相同的内容(对于新读者来说,位置和想法隐藏得很好)。然而,对其他答案的推荐应该被删除/不在顶部;这个例子应该足够完整,比如
new.function(spam\u code\u object,globals())(“一些鸡蛋”)
。(Python 2.7和2.6还支持
func.\uu code\uu
,除了
func.func\u code
)将此与结合起来,我认为您有一个完整的工作答案,尽管我无法获得链接的答案来做任何事情
import new
newFunction = new.function(codeObject, globals())