landee
landee

Reputation: 45

How to use eval() in a function from library with functions which are defined outside of this library?

I have recently developed and uploaded to PyPI a library which has a function where eval() is used:

def adv_prod(start,end,rule):
    ending_seq = list_prod([eval(rule) for i in range(start,end+1)])
    return ending_seq

If rule argument gets a string with in-library function, it works fine (prime(i) is defined in the same library file):

from supMath import adv_prod,prime

for x in range(1,11):
    print(adv_prod(1,x,"prime(i)")) 

Output:

2
6
30
210
2310
30030
510510
9699690
223092870
6469693230

But as soon as i try to input an outer function or a function from different library module I get NameError:

from supMath import adv_prod

def fib(n):
    if n==1:
        return 1
    if n==2:
        return 1
    return fib(n-2)+fib(n-1)

for x in range(1,11):
    print(adv_prod(1,x,"fib(i)")) 

Output: NameError: name 'fib' is not defined

Upvotes: 1

Views: 74

Answers (2)

phd
phd

Reputation: 94716

This how you should do it without eval at all. Pass the function and apply/call it inside adv_prod:

def adv_prod(start, end, rule):
    ending_seq = list_prod([rule(i) for i in range(start, end+1)])
    return ending_seq
from supMath import adv_prod, prime

for x in range(1, 11):
    print(adv_prod(1, x, prime)) 
from supMath import adv_prod

def fib(n):
   …

for x in range(1, 11):
    print(adv_prod(1, x, fib)) 

Upvotes: 2

James
James

Reputation: 42

I was trying to recreate this but I don't have access to the list prod function, however I do believe I know what is going on. To access external variables using eval, you can add an extra parameter, globals(), to use all global variables/funcs etc, for example:

def adv_prod(start,end,rule):
   ending_seq = list_prod([eval(rule, globals()) for i in range(start,end+1)])
   return ending_seq

Let me know if this works!

Upvotes: -2

Related Questions