通过导入模块中的exec动态定义函数 [英] Dynamically defined functions via exec in imported module

查看:84
本文介绍了通过导入模块中的exec动态定义函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,

我正在尝试编写一个能够通过exec动态生成其他

函数的函数。然后我希望能够导入包含此功能的文件(模块)

并在其他模块中使用它,但是对于某些

的原因它只能使用 import< mod>"语法,而不是来自

< modimport *语法...即在后一种情况下,函数是动态生成的
,但无法从导入模块访问。

关于我能做什么的任何想法都能够保留第二种形式的

导入并仍然可以看到exec'的功能?


这里是代码......我有三个文件:


#################################### br $> b $ b#modA.py

def dynamicdef(name,amt):

''''''动态定义一个新函数使用给定名称

将给定的amt添加到其参数中并返回结果。'''''''

stm =" ; def%s(x):\ n \treturn x +%d" %(姓名,amt)

打印stm

#exec stm#---这个,''name''只能在
$ b $内访问b这个fn

exec stm in globals()#---这使得它在这个

模块中全球化......


print eval(姓名)

dynamicdef(''plus5'',5)


打印加5(7)

# ##################################

#modB.py

#这使用dynamicdef动态定义一个新函数,并且



#工作正常,新定义的函数可通过
访问
modA

#模块......


导入modA


modA.dynamicdef(' 'plus10'',10)


打印帮助(modA.plus5)

打印帮助(modA.plus10)


打印modA.plus5(20)

打印modA.plus10(20)


############# ######################

#modC.py

#这使用dynamicdef动态定义一个新的功能,但



#不起作用;好像知道新定义的函数在



#modA模块没有传播回这个上下文或什么......?

来自modA导入的
*

dynamicdef(''plus10'',10)


打印帮助(plus5)

#print help(plus10)#!!!失败:NameError:名称''plus10''不是

定义


打印加5(20)

打印加10(20 )

###################################

感谢您的任何帮助/建议,

--- nadeem

解决方案

8月15日, 7:26 * pm,Nadeem< nadeemabdulha ... @ gmail.comwrote:


大家好,

我正在尝试编写一个函数,通过exec动态生成其他

函数。



一般提示:每当你认为你需要使用exec(或eval)时,99%的

你没有时间;大部分时间都有一个更好的(意思是,更少的b $ b b b脆弱和模糊)解决方案。


>然后我希望能够导入文件(模块)

包含此功能并在其他模块中使用它,但对于某些

原因它只能使用import< mod> ;语法,而不是来自

< modimport *语法...即在后一种情况下,函数是动态生成的
,但无法从导入模块访问。

关于我能做什么的任何想法都能够保留第二种形式的

导入并仍然可以看到exec'的功能?


这里是代码......我有三个文件:


#################################### br $>
#modA.py


def dynamicdef(name,amt):

* *''''''动态定义一个具有给定名称的新函数

添加

* *给定的参数amt并返回结果。''''''

* * stm =" def%s(x):\ n \treturn x +%d" %(姓名,amt)

* *打印stm

* * #exec stm * * *#---这个,''name''只能在

这个fn

* * exec stm in globals()*#---这使得它在这个

模块中是全局的...


* * print eval(姓名)


dynamicdef(''plus5'',5)


print plus5(7)



不出所料,确实有更好的方法,关闭:


def adder( amt):

def closure(x):

返回x + amt

返回结束


>> plus5 = adder(5)
plus5(7)



12

HTH,

George


< blockquote>我理解99%规则...我给出的例子是简化

问题。我正在做的全部工作是一个图书馆,用于介绍我正在教授的CS $ b $ CS课程。实际上,我正在尝试构建一个

宏库供学生使用,允许他们使用选择器函数定义记录(例如在C中使用
结构)。特别是,我正在尝试使用
从Python中的HtDP项目中复制一些Scheme内容

http://www.htdp.org/2003-09-26/Book/curriculum-Z-

H-9.html#node_sec_6.3)。我想提供一个名为

defineStruct的函数,它被调用如下:


defineStruct(''pos'',''x'',' 'y'')


这个函数的作用是动态定义几个新的

函数来处理结构:

makePos(x,y)

posX(p)

posY(p)

isPos(p)

我明白这一切都可以通过课程和OO

编程完成,但HtDP课程的重点是

介绍学生用教学效果的方式编程

使用功能方法而不是OO优先。他们在Scheme中这样做,

主要是f.p.语言,我正试图在Python中复制一个类似于

的方法。 defineStruct的东西基本上是指<​​br />
是一个宏,它引入了一组函数,无论是什么需要
结构定义。


因此,由于这些原因,我不相信上面的关闭示例是有用的。我不想告诉学生关于

闭包的任何事情,当然让他们担心函数返回

函数和函数指针等等。我'我试图在幕后捆绑所有




所以,再想一想我的问题,另一个问题可能是:是

在模块中调用的函数中,可以访问和更新调用程序模块中的全局定义(字典或其他)



--- nadeem


好吧,我发现一个hack似乎是通过访问最外层的

globals()字典来达到这个目的的堆叠框架并为新创建的功能添加一个条目




导入检查


def dynamicdef (姓名,amt):

''''''动态定义一个具有给定名称的新函数

添加

给定的amt它的论点和回归结果。'''''''

stm =" def%s(x):\ n \treturn x +%d" %(姓名,amt)

打印stm

执行stm in globals()


##添加这个以导出新的功能名称到顶级......

inspect.stack()[ - 1] [0] .f_globals [name] = eval(姓名)

我想我除非有人建议替补,否则我会选择这个。谢谢

无论如何,:)

--- nadeem


Hello all,
I''m trying to write a function that will dynamically generate other
functions via exec. I then want to be able to import the file (module)
containing this function and use it in other modules, but for some
reason it only works using the "import <mod>" syntax, and not "from
<modimport *" syntax... i.e. in the latter case, the function is
dynamically generated, but not accessible from the importing module.
Any ideas on what I can do to be able to retain the second form of
import and still have the exec''d functions visible?

Here''s the code... I have three files:

###################################
# modA.py

def dynamicdef(name, amt):
''''''Dynamically defines a new function with the given name that
adds
the given amt to its argument and returns the result.''''''
stm = "def %s(x):\n\treturn x + %d" % (name, amt)
print stm
# exec stm # --- with this, ''name'' is only accessible within
this fn
exec stm in globals() # --- this makes it global within this
module...

print eval(name)
dynamicdef(''plus5'', 5)

print plus5(7)
###################################
# modB.py
# This uses the dynamicdef to dynamically define a new function, and
it
# works fine, with the newly defined function being accessible thru
the modA
# module...

import modA

modA.dynamicdef(''plus10'', 10)

print help(modA.plus5)
print help(modA.plus10)

print modA.plus5(20)
print modA.plus10(20)

###################################
# modC.py
# This uses the dynamicdef to dynamically define a new function, but
it
# doesn''t work; seems like knowledge of the newly defined function in
the
# modA module is not propagated back to this context or something...?

from modA import *

dynamicdef(''plus10'', 10)

print help(plus5)
#print help(plus10) # !!! Fails: NameError: name ''plus10'' is not
defined

print plus5(20)
print plus10(20)
###################################
Thanks for any help/suggestions,
---nadeem

解决方案

On Aug 15, 7:26*pm, Nadeem <nadeemabdulha...@gmail.comwrote:

Hello all,
I''m trying to write a function that will dynamically generate other
functions via exec.

General tip: whenever you think you need to use exec (or eval), 99% of
the time you don''t; most of the time there is a better (meaning, less
fragile and obscure) solution.

>I then want to be able to import the file (module)
containing this function and use it in other modules, but for some
reason it only works using the "import <mod>" syntax, and not "from
<modimport *" syntax... i.e. in the latter case, the function is
dynamically generated, but not accessible from the importing module.
Any ideas on what I can do to be able to retain the second form of
import and still have the exec''d functions visible?

Here''s the code... I have three files:

###################################
# modA.py

def dynamicdef(name, amt):
* * ''''''Dynamically defines a new function with the given name that
adds
* * the given amt to its argument and returns the result.''''''
* * stm = "def %s(x):\n\treturn x + %d" % (name, amt)
* * print stm
* * # exec stm * * *# --- with this, ''name'' is only accessible within
this fn
* * exec stm in globals() * # --- this makes it global within this
module...

* * print eval(name)

dynamicdef(''plus5'', 5)

print plus5(7)

Unsurprisingly, there is indeed a better way, a closure:

def adder(amt):
def closure(x):
return x + amt
return closure

>>plus5 = adder(5)
plus5(7)

12

HTH,
George


I understand the 99% rule... the example I gave was to simplify the
issue. The full thing I''m working on is a library for an introductory
CS class I''m teaching. I''m trying, essentially, to build a library of
macros for students to use allowing them to define records (like
structs in C) with selector functions. In particular, I''m trying to
replicate some of the Scheme stuff from the HtDP project in Python
(http://www.htdp.org/2003-09-26/Book/curriculum-Z-
H-9.html#node_sec_6.3). I want to provide a function, called
defineStruct that is called like this:

defineStruct(''pos'', ''x'', ''y'')

The effect of this function will be to dynamically define several new
functions for working with structures:

makePos(x, y)
posX(p)
posY(p)
isPos(p)

I understand that all this can be done with classes and OO
programming, but the whole point of the HtDP curriculum is to
introduce students to programming in a pedagogically-effective way
using a functional approach instead of OO-first. They do it in Scheme,
which is primarily a f.p. language, and I''m trying to replicate a
similar approach in Python. The defineStruct thing is basically meant
to be a macro that introduces a set of functions for whatever
structure definition is needed.

So, for these reasons, I don''t believe the closure example above is
helpful. I don''t want to have to tell students anything about
closures, and certainly have them worrying about functions returning
functions, and function pointers, etc. I''m trying to bundle all that
up behind the scenes.

So, thinking about my problem again, an alternate question may be: Is
it possible, in a function called in a module, to access and update
the global definitions (dictionary or whatever) in the caller module.

--- nadeem


Well, I found one hack that seems to achieve this by accessing the
globals() dictionary of the outermost stack frame and adding an entry
to it for the newly created functions:

import inspect

def dynamicdef(name, amt):
''''''Dynamically defines a new function with the given name that
adds
the given amt to its argument and returns the result.''''''
stm = "def %s(x):\n\treturn x + %d" % (name, amt)
print stm
exec stm in globals()

## ADDED THIS TO EXPORT THE NEW FUNCTION NAME TO THE TOP LEVEL...
inspect.stack()[-1][0].f_globals[name] = eval(name)
I guess I''ll go with this unless someone suggests an alternate. Thanks
anyway, :)
--- nadeem


这篇关于通过导入模块中的exec动态定义函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆