使用exec生成代码的习惯用法 [英] An idiom for code generation with exec

查看:77
本文介绍了使用exec生成代码的习惯用法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好,


在Python程序中我写的是我需要动态生成

函数[*]并将它们存储在dict中。 eval()不能为我工作

因为函数定义是一个语句而不是表达式,所以

我正在使用exec。目前我提出以下内容使其成为

工作:


def build_func(args):

code" ;"" def foo(...)...""

d = {}

执行代码在globals(),d

返回d [''foo'']


我的问题是,考虑到我真的需要代码生成[*] -

有更清洁的方法吗?另外,如果我用无替换

globals()会发生什么?

另外,我发现缩进是这样的问题

构造。是否有一种可行的方法来缩进代码在

build_func的水平,而不是在第0列?


提前谢谢

Eli

[*]我知道每次代码生成问题出现时人们都会建议有更好的方法来实现这一点,而不使用exec,

eval等等。但在我的情况下,由于原因太长而无法完全布局,我确实需要生成具有大量硬编码的非平凡函数

表现的行动。并且没有安全问题

无论如何。如果有人对该应用程序非常感兴趣,我会详细说明。


Hello,

In a Python program I''m writing I need to dynamically generate
functions[*] and store them in a dict. eval() can''t work for me
because a function definition is a statement and not an expression, so
I''m using exec. At the moment I came up with the following to make it
work:

def build_func(args):
code """def foo(...)..."""
d = {}
exec code in globals(), d
return d[''foo'']

My question is, considering that I really need code generation[*] -
"is there a cleaner way to do this ?" Also, what happens if I replace
globals() by None ?
Additionally, I''ve found indentation to be a problem in such
constructs. Is there a workable way to indent the code at the level of
build_func, and not on column 0 ?

Thanks in advance
Eli
[*] I know that each time a code generation question comes up people
suggest that there''s a better way to achieve this, without using exec,
eval, etc. But in my case, for reasons too long to fully lay out, I
really need to generate non-trivial functions with a lot of hard-coded
actions for performance. And there''s no problem of security
whatsoever. If someone is very interested in the application, I will
elaborate more.


推荐答案

elibenaécrit:
eliben a écrit :

你好,


在Python程序中我写的是我需要动态生成

函数[*]
Hello,

In a Python program I''m writing I need to dynamically generate
functions[*]



(剪辑)

(snip)


[*] I知道每次代码生成问题出现时人们都会建议有更好的方法来实现这一点,不使用exec,

eval等等。
[*] I know that each time a code generation question comes up people
suggest that there''s a better way to achieve this, without using exec,
eval, etc.



只是为了说清楚:你知道你可以在没有exec的情况下动态构建

函数,是吗?

Just to make things clear: you do know that you can dynamically build
functions without exec, do you ?


但在我的情况下,由于原因太长而无法完全布局,我确实需要生成具有大量硬编码的非平凡函数

表现的行动。
But in my case, for reasons too long to fully lay out, I
really need to generate non-trivial functions with a lot of hard-coded
actions for performance.



只是出于好奇:你能不能多说一下你的用例

是什么让一个简单的关闭不是一个选项? br />

Just out of curiousity : could you tell a bit more about your use case
and what makes a simple closure not an option ?


并且没有安全问题

无论如何。如果有人对该应用程序非常感兴趣,我会详细说明。
And there''s no problem of security
whatsoever. If someone is very interested in the application, I will
elaborate more.


6月20日上午9:17,Bruno Desthuilliers< bruno。

42.desthuilli ... @ websiteburo .invalidwrote:
On Jun 20, 9:17 am, Bruno Desthuilliers <bruno.
42.desthuilli...@websiteburo.invalidwrote:

elibenaécrit:Hello,
eliben a écrit :Hello,

在Python程序中我正在写我需要动态生成

函数[*]
In a Python program I''m writing I need to dynamically generate
functions[*]



(剪辑)


(snip)


[*]我知道,每次代码生成问题出现时,人们都会建议有更好的方法来实现这一点,而不使用exec,

eval等等
[*] I know that each time a code generation question comes up people
suggest that there''s a better way to achieve this, without using exec,
eval, etc.



只是为了说清楚:你知道你可以动态建立

函数而不用exec,对吗? />


Just to make things clear: you do know that you can dynamically build
functions without exec, do you ?



是的,但这样做的其他选项明显少于执行的灵活性。

Yes, but the other options for doing so are significantly less
flexible than exec.


但在我的c中ase,由于原因太长而无法完全布局,我确实需要使用大量硬编码的b / b
性能来生成非平凡的函数。
But in my case, for reasons too long to fully lay out, I
really need to generate non-trivial functions with a lot of hard-coded
actions for performance.



只是出于好奇:你能不能多说一下你的用例

是什么让一个简单的关闭不是一个选项?


Just out of curiousity : could you tell a bit more about your use case
and what makes a simple closure not an option ?



好​​的。


我在嵌入式编程领域工作,其中一个主要用途是

我用Python(以及之前的Perl)正在为控制嵌入式系统的

编写GUI。通信协议通常是基于串口

通信(RS232)构建的特殊消息(headear,footer,data,crc)。


到达的数据包具有已知格式。例如(YAMLish

语法):


packet_length:10

字段:

- 名称:标题

抵消:0

长度:1

- 名称:time_tag

抵消:1

长度:1

变换:val * 2048

单位:ms

- 名称:counter

抵消:2

长度:4

bytes-msb-first:true

- 名称:bitmask

偏移量:6

长度:1

bit_from:0

bit_to:5

...


这是部分功能显示。字段已经定义了偏移量和

长度,可以只有几位长,可以定义

转换和单位以方便显示。


我有一个程序应该从串口接收这样的数据包

并以表格形式显示它们的内容。我希望用户能够

在类似于上面的文件中指定其数据包的格式。


现在,在此代码的先前版本中,用Perl编写的,我发现

,从数据包中提取字段值的过程非常低效。我已经使用动态生成的程序重写了它,每个字段都有
,它对其数据进行硬编码访问。例如:


def get_counter(包):

data = packet [2:6]

data.reverse()

返回数据


这给了我一个巨大的加速,因为每个字段现在都有一个特定的

函数坐在一个字典中从给定的数据包中快速提取字段的数据




现在我用Python重写这个程序,我想知道这个/>
使用exec的惯用方法(在Perl中,eval()替换eval和exec

的Python)。


Eli

Okay.

I work in the field of embedded programming, and one of the main uses
I have for Python (and previously Perl) is writing GUIs for
controlling embedded systems. The communication protocols are usually
ad-hoc messages (headear, footer, data, crc) built on top of serial
communication (RS232).

The packets that arrive have a known format. For example (YAMLish
syntax):

packet_length: 10
fields:
- name: header
offset: 0
length: 1
- name: time_tag
offset: 1
length: 1
transform: val * 2048
units: ms
- name: counter
offset: 2
length: 4
bytes-msb-first: true
- name: bitmask
offset: 6
length: 1
bit_from: 0
bit_to: 5
...

This is a partial capability display. Fields have defined offsets and
lengths, can be only several bits long, can have defined
transformations and units for convenient display.

I have a program that should receive such packets from the serial port
and display their contents in tabular form. I want the user to be able
to specify the format of his packets in a file similar to above.

Now, in previous versions of this code, written in Perl, I found out
that the procedure of extracting field values from packets is very
inefficient. I''ve rewritten it using a dynamically generated procedure
for each field, that does hard coded access to its data. For example:

def get_counter(packet):
data = packet[2:6]
data.reverse()
return data

This gave me a huge speedup, because each field now had its specific
function sitting in a dict that quickly extracted the field''s data
from a given packet.

Now I''m rewriting this program in Python and am wondering about the
idiomatic way to use exec (in Perl, eval() replaces both eval and exec
of Python).

Eli


eliben写道:
eliben wrote:

此外,我发现缩进是一个问题

构造。是否有一种可行的方法在

build_func级别缩进代码,而不是在第0列?
Additionally, I''ve found indentation to be a problem in such
constructs. Is there a workable way to indent the code at the level of
build_func, and not on column 0 ?



exec" if 1:" + code.rstrip()


彼得

exec "if 1:" + code.rstrip()

Peter


这篇关于使用exec生成代码的习惯用法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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