473,785 Members | 2,290 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Do eval() and exec not accept a function definition? (like 'def foo: pass) ?


Hi group,

Question: Do eval() and exec not accept a function definition? (like
'def foo: pass) ?

I wrote a function to generate other functions using something like
eval("def foo: ....")
but it gave a syntax error ("Invalid syntax") with caret pointing to
the 'd' of the def keyword.

Details (sorry for the slight long post but thought it better to give
more details in this case - wording is pretty clear, though, I think,
so shouldn't take long to read):

While working on a personal project for creating a server for a
certain protocol (which I may make into an open source project later
if it turns out to be any good), I wrote some simple functions to
generate HTML start and end tags like <html>, <body>, </html>, </
body>, etc. - just to simplify/shorten my code a little. (I'm aware
that there are HTML generation libraries out there, but don't think I
need the overhead, since my needs are very simple, and anyway wanted
to roll my own just for fun. For a bigger/more serious project I would
probably use the existing libraries after doing a proper evaluation).
So, this question is not about HTML generation but about Python's
eval() function and exec statement.

Started by writing functions like this:

def start_html():
return '<html>\r\n'

def end_html():
return '</html>\r\n'

.... and similarly for the 'body', 'p', etc. HTML tags.
(I used '\r\n' at the end because the server will send this output to
the browser over HTTP, so that my code conforms to Internet protocols,
and also so that while debugging, my output would have only one tag
per line, for readability. Not showing the '\r\n in the rest of the
code below)

Then I realized that all these functions are very similar - only
differ in the return value of the tag.
So (being interested in metaprogramming of late), thought of writing a
function that would generate these functions, when passed the
appropriate tag name argument.

[ Digression: I could of course have used another simple approach such
as this:

def start_tag(tag_n ame):
return '<' + tag_name + '>'

# called like this:
# print start_tag('html ')
# print start_tag('body ')

# and

def end_tag(tag_nam e):
return '</' + tag_name + '>'

# called like this:
# print end_tag('body')
# print end_tag('html')

# and called similarly for the other HTML tags.

While the above would work, it still would involve a bit more typing
than I'd like to do, since I'[d have to pass in the tag name as an
argument each time. I'd prefer having functions that I could call like
this:

print start_html()
# which would print "<html>"
print start_body()
# which would print "<body>"

# and so on ... just to make the code a little shorter and more
readable.

End of Digression]

So, I wrote this code generation function:

# AAAA
import string
def generate_html_t ag_function(tag _name, start_or_end):
start_or_end.lo wer()
assert(start_or _end in ('start', 'end'))
if start_or_end == 'start':
func_def = "def start_" + tag_name + ":()\n" + \
"return '<' + tag_name + '>'
else:
func_def = "def end_" + tag_name + ":()\n" + \
"return '</' + tag_name + '>'
function = eval(func_def)
return function

# meant to be called like this:

start_html = generate_html_t ag_function('ht ml', 'start')
start_body = generate_html_t ag_function('bo dy', 'start')
end_html = generate_html_t ag_function('ht ml', 'end')
end_body = generate_html_t ag_function('bo dy', 'end')

# and the generated functions would be called like this:

print start_html()
print start_body()
print end_body()
print end_html()
# BBBB

# giving the output:
<html>
<body>
</body>
</html>

But when I ran the above code (between the lines marked #AAAA and
#BBBB), I got an error "Invalid syntax" with the caret pointing at the
"d" of the def statement.
I had used eval a few times earlier for somewhat similar uses, so
thought this would work.
I then looked up the Python Language Reference help, and saw that eval
is used to evaluate Python expressions, not statements, and def is a
statement. So looked up the exec statement of Python and saw that its
syntax seemed to allow what I wanted.
So replaced the line containing eval in the above with:
exec(func_def)
But that too gave the same error (I think so - I tried this yesterday
and forgot to save the error messages, sorry about that, so can't be
sure, but do think this was the case - if not, I'll save the exact
code and output/errors later and repost here - not at my PC right
now.)

Thanks for any suggestions,

Vasudev Ram
Bize site: http://www.dancingbison.com
PDF creation / conversion toolkit: http://sourceforge.net/projects/xtopdf
Blog on software innovation: http://jugad.livejournal.com

Jun 23 '07 #1
6 3633
MC
Hi!

Try with change all '\r\n' by '\n'

--
@-salutations

Michel Claveau
Jun 23 '07 #2
Hey,

I think you could use lambda functions for that matter (Ever heard of
them?). You could write something like:

def generate_html_t ag_function(tag _name, start_or_end):
start_or_end.lo wer()
assert(start_or _end in ('start', 'end'))
if start_or_end == 'start':
function = lambda: '<' + tag_name + '>'
else:
function = lambda: '</' + tag_name + '>'
return function

Then you would create the functions using the same code you had
written before:

start_html = generate_html_t ag_function('ht ml', 'start')
start_body = generate_html_t ag_function('bo dy', 'start')
end_html = generate_html_t ag_function('ht ml', 'end')
end_body = generate_html_t ag_function('bo dy', 'end')
That seems to do what you want.

Eduardo

Jun 23 '07 #3
On Jun 24, 1:20 am, Eduardo Dobay <edudo...@gmail .comwrote:
Hey,

I think you could use lambda functions for that matter (Ever heard of
them?). You could write something like:

def generate_html_t ag_function(tag _name, start_or_end):
start_or_end.lo wer()
assert(start_or _end in ('start', 'end'))
if start_or_end == 'start':
function = lambda: '<' + tag_name + '>'
else:
function = lambda: '</' + tag_name + '>'
return function

Then you would create the functions using the same code you had
written before:

start_html = generate_html_t ag_function('ht ml', 'start')
start_body = generate_html_t ag_function('bo dy', 'start')
end_html = generate_html_t ag_function('ht ml', 'end')
end_body = generate_html_t ag_function('bo dy', 'end')

That seems to do what you want.

Eduardo
Thanks to all the repliers.

@Eduardo: Yep, I had heard of lambdas, but didn't think to use them
here.
Will try this out - thanks!

- Vasudev
Jun 23 '07 #4
vasudevram wrote:
Hi group,

Question: Do eval() and exec not accept a function definition? (like
'def foo: pass) ?
def is the first keyword in a _statement_, not an expression.

exec executes statements, eval evaluates expressions.

try this:

exec "def foolish(x):\n y= x * 2\n print x, y"
foolish(2.4)
--
--Scott David Daniels
sc***********@a cm.org
Jun 23 '07 #5
On Sat, 23 Jun 2007 19:58:32 +0000, vasudevram wrote:
>
Hi group,

Question: Do eval() and exec not accept a function definition? (like
'def foo: pass) ?
eval() is a function, and it only evaluates EXPRESSIONS, not code blocks.

eval("2+3") # works
eval("x - 4") # works, if x exists
eval("print x") # doesn't work

exec is a statement, and it executes entire code blocks, including
function definitions, but don't use it. Seriously.

ESPECIALLY don't use it if you are exec'ing data collected from untrusted
users, e.g. from a web form.

I wrote a function to generate other functions using something like
eval("def foo: ....")
but it gave a syntax error ("Invalid syntax") with caret pointing to
the 'd' of the def keyword.
You don't need eval or exec to write a function that generates other
functions. What you need is the factory-function design pattern:
def factory(arg):
def func(x):
return x + arg
return func

And here it is in action:
>>plus_one = factory(1)
plus_two = factory(2)
plus_one(5)
6
>>plus_two(5)
7

--
Steven.

Jun 24 '07 #6
On Jun 24, 6:28 am, Jean-Paul Calderone <exar...@divmod .comwrote:
On Sun, 24 Jun 2007 11:17:40 +1000, Steven D'Aprano <s...@remove.th is.cybersource. com.auwrote:
On Sat, 23 Jun 2007 19:58:32 +0000, vasudevram wrote:
Hi group,
Question: Do eval() and exec not accept a function definition? (like
'def foo: pass) ?
eval() is a function, and it only evaluates EXPRESSIONS, not code blocks.

Actually, that's not exactly true:
>>x = compile('def foo():\n\tprint "hi"\n', '<stdin>', 'exec')
>>l = {}
>>eval(x, l)
>>l['foo']()
hi
>>>

Jean-Paul
Thanks, all. Will check out the replies given.
- Vasudev

Jun 24 '07 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
2032
by: Jean-Sébastien Bolduc | last post by:
Hello, I would like to associate a local namespace with a lambda function. To be more specific, here is exactly what I would want: def foo(): a = 1 f = lambda x : a*x return f
1
1758
by: Art | last post by:
Hello, I can't seem to get eval or compile to accept the print stmt, or any complicated statements. The documentation I've looked out doesn't explain why this is. ex: >>> eval("print('foo')") Traceback (most recent call last):
1
2230
by: Andr? Roberge | last post by:
I have the following two files: #--testexec.py-- def exec_code(co): try: exec co except: print "error" #-- test.py--
2
1398
by: pasa | last post by:
I'm an old time python user, but just got bitten by namespaces in eval. If this is an old discussion somewhere, feel free to point me there. Based on the documentation, I would have expected the following to work: def foo(k): print k; print a ns = {'a':1, 'foo': foo} eval('foo(2)', ns)
10
2404
by: Julian Smith | last post by:
I've been playing with a function that creates an anonymous function by compiling a string parameter, and it seems to work pretty well: def fn( text): exec 'def foo' + text.strip() return foo This can be used like: def foo( x):
10
409
by: Antoon Pardon | last post by:
I have the following little piece of code: class Cfg:pass #config = Cfg() def assign(): setattr(config, 'Start' , ) def foo(): config = Cfg()
4
2372
by: Michael | last post by:
Hi, I'm having difficulty finding any previous discussion on this -- I keep finding people either having problems calling os.exec(lepev), or with using python's exec statement. Neither of which I mean here. Just for a moment, let's just take one definition for one of the
6
151
by: dave.g1234 | last post by:
Suppose I have a function in module X that calls eval e.g, X.py _______ Def foo(bar): Eval(bar) _______ Now eval will be called using the default eval(bar,globals(),locals()) and globals will pull in anything in module X.
2
1654
by: Danny Shevitz | last post by:
Howdy, In my app I need to exec user text that defines a function. I want this function to unpickle an object. Pickle breaks because it is looking for the object definition that isn't in the calling namespace. I have mocked up a simple example that shows the problem. Run this first code (from create_pickle.py) to create the pickle. create_pickle.py: (run this first)
0
9646
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
10350
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
10097
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9957
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8983
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7505
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5386
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5518
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4055
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.