1

I have the following eval() thing:

c = Customer()
eval("c.name = row.value('customer', '{c}')".format(c=column_name), { 'c': c, 'row': row})

When I try to run that, I get this:

Traceback (most recent call last):
  File "./import.py", line 19, in <module>
    c = Customer.save_from_row(row)
  File "/home/jason/projects/mcifdjango/mcif/models/customer.py", line 43, in save_from_row
    eval("c.name = row.value('customer', '{c}')".format(c=column_name), { 'c': c, 'row': row})
  File "<string>", line 1
    c.name = row.value('customer', 'name')
           ^
SyntaxError: invalid syntax

What am I doing wrong?

Edit: Because it looks like I didn't explain the context of my problem well enough, here's what I ended up doing, if anyone's curious:

@classmethod
def save_from_row(cls, row):
    c = cls()
    map(lambda column_name: setattr(c, column_name, row.value('customer', column_name)), c.distinguishing_column_names())
    return c.upsert()

Before I found out about setattr() I was separately setting several different attributes on c.

Jason Swett
  • 43,526
  • 67
  • 220
  • 351

2 Answers2

11

eval evaluates expressions. Assignment is a statement, not an expression.

And don't even get me started on how easily misused and - in 99.99% of all cases - utterly unnecesary eval is. Just refer to the numerous other eval questions, I bet each has at least one such rant in an answer or comment - so I'll save my breath and link to one I like. (That being said, exec works like eval for statements.)

Community
  • 1
  • 1
  • Any recommendation for what I might do instead of eval? – Jason Swett Feb 01 '11 at 19:41
  • 1
    @Jason: Depends on what you need. In general, if you are emulating [PHP's variable variables](http://www.php.net/manual/en/language.variables.variable.php) - i.e. associate values with strings - a dictionary will do work as well while preserving sanity (and be orders of magnitude faster while we're at it). –  Feb 01 '11 at 19:47
2

Wouldn't this do what you need?:

c = Customer()
name_cols = (('name', 'custname'), ('addr', 'cust_addr'))
for name, col in name_cols:
    setattr(c, name, row.value('customer', col))
Ned Batchelder
  • 364,293
  • 75
  • 561
  • 662