Python Forum
using function through exec()
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
using function through exec()
#1
Hi, I'm trying to call a function defined out of exec() within the exec(), but I'm getting an error saying that the fuction I'm trying to run is not found. It works if I do something like this:
def a():
    print("hi")
txt = "a()"
exec(txt)
but In my case it is something more like this i'm simplifying cause my code is almost 500 line:
class b():
    def __init__(self):
        self.button()
    def button(self):
        def a():
            print("hi")
        txt = "a()\n print("example")"
        exec(txt)    
here is what this portion of my code looks like:
def BRun(self, e):
        def Pt(self, x, y):
            plt.scatter(x, y)
            try:
                canvas.draw()
                
            except NameError:
                pass
            self._mgr.Update()
        file = open(File)
        exec(file.read())
and here is the file that is being opened:
##-- temp --##
import matplotlib.pyplot as plt
import random
##-- end  --##


# DataX is just for graphing purposes
#DATAX = []
# Raw data to be read 
#DATAY = [1,1,1,1,1,1,1,1,1,1,1,1,1,2,3,4,5,6,7,8,9,8,7,6,5,4,3,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]

# Running average graphing
AvgY = []
AvgY2 = []
AvgX = []
##----------------------------------------#
#######-- FPGA Memory Buffer --############
Mem0Width = 5
Mem0 = []
Mem1 = []
Mem2 = []
sum0 = 0
sum1 = 0
sum2 = 0
## raise detectiom
rise0 = False
#rise1 = False
comp0 = False
comp1 = False
comp2 = False
##----------------------------------------#
#######-- Simulate fpga run time --#######
##----------------------------------------#
def runtime():
    global Mem0Width
    global Mem0
    global Mem1
    global Mem2
    global AvgX
    global AvgY
    global AvgY2
    
    # peak det
    global rise0
    #global rise1
    global comp0
    global comp1
    global comp2
    
    global sum0
    global sum1
    global sum2
    
    for i in range(0, len(DATAY), Mem0Width):
        Mem2 = Mem1
        Mem1 = Mem0
        if not i <= Mem0Width or not len(DATAY)-Mem0Width:
            Mem0 = DATAY[i-Mem0Width:i]
        if i <= Mem0Width:
            Mem0 = []
            for z in range(Mem0Width-i):
                Mem0.append(DATAY[z])
            for z in range(i):
                Mem0.append(DATAY[z])
        if i >= len(DATAY)-Mem0Width:
            Mem0 = []  
            for z in range(-i+len(DATAY)):
                Mem0.append(DATAY[i])
            for z in range(+i-len(DATAY)+Mem0Width):
                Mem0.append(DATAY[z])
        
        ##----------------------------------------#
        ########-- add runtime code here --########
        ##----------------------------------------#
        ######-- code to be applied in FPGA--######
        ##----------------------------------------#        
        ## running average
        Sum = 0
        for z in range(len(Mem0)):
            Sum += Mem0[z]
        ##-- memory -- ##
        sum2 = sum1
        sum1 = sum0
        sum0 = Sum
        ##-- peak det --##
        comp2 = comp1
        comp1 = comp0
        if sum0 > sum1:
            comp0 = True
        if sum0 <= sum1:
            comp0 = False
        ## rise detect
        if comp0 and comp1 and comp2:
            rise0 = True
        ## when rise starts to fall log max value
        if rise0 is True and comp0 is False and comp1 is True and comp2 is True:
            peak = 0
            for q in range(len(Mem1)):
                if Mem1[q] > peak:
                    peak = Mem1[q]
            print(peak)
            Pt(i, peak)
        if comp0 is False:
            rise0 = False
        

        ## for graphing only
        AvgY.append(Sum)
        AvgY2.append(Sum/Mem0Width)
##----------------------------------------#
#######-- Generate noise & x axis --#######
################-- Test --#################
##----------------------------------------#    
def xGen():
    for i in range(len(DATAY)):
        DATAX.append(i)
        DATAY[i] += random.random()


#xGen()
runtime()
#plt.plot(DATAX, DATAY, color = 'red') # data
#plt.plot(DATAX, AvgY, color = 'blue') #sum
#plt.plot(DATAX, AvgY2, color = 'blue')
#plt.show()
if I leave out Pt(i, peak) from the code it runs, but with it I get the following error message:
Error:
Traceback (most recent call last): File "C:\Users\Daniel\eclipse-workspace\program\src\Prog.py", line 301, in BRun exec(file.read()) File "<string>", line 121, in <module> File "<string>", line 102, in runtime NameError: name 'Pt' is not defined
Reply
#2
You could just... not use exec...

It's a file, and apparently python code, so... import it? exec is in the same family of things that really shouldn't be used unless there's no other choice, along with eval global goto and javascript.
Reply
#3
This code shows many beginner's idioms, such as the massive use of global statements and a non natural way to nest functions definitions. One can nest functions definitions in python, but it is not for beginners, and it can always be avoided. It means that you can write the best python code without nesting more than this:
def spam():
    pass

class Eggs:
    def ham(self):
        pass
The nesting of function definitions and the calls to exec() in this code show attempts to write and use python code by inlining 'macros'. As Nilamo suggests above, this is not the correct way to write python code.

What can you do? Suppose the file that you want to exec is named spamham.py. You can first remove the call to runtime() at the end of this file. Then as the function uses Pt, you can pass it as a parameter like this
# file spamham.py
def runtime(Pt):
    ...
Now in the main code, write
# main program
from spamham import runtime
...
class Eggs:
    def BRun(self, e)
        runtime(self.Pt)

    def Pt(self, x, y):
        plt.scatter(x, y)
        try:
            canvas.draw()
                
        except NameError:
            pass
        self._mgr.Update()
Reply
#4
Quote:It's a file, and apparently python code, so... import it?
it's possible it's just that I want the file to be editable within the application I'm writing, that's why I thought it best to try to execute the function, since the string in the textbox will be easy to access and also I don't really like the idea of dynamically importing things since the file can be changed while the program is running. I'll try importing within the function instead thanks, I hadn't thought about it as a possibility.

Quote:This code shows many beginner's idioms
yes that is true, I tend to use python if I want something quick or if I need matplotlib, so I'm not proficient at it.
Quote:One can nest functions definitions in python, but it is not for beginners, and it can always be avoided. It means that you can write the best python code without nesting more than this
I agree with you, but for this script nesting some parts were easier and more intuitive for me because I'm still getting used to wxpython.
Reply
#5
The problem with using exec in this manner is that the file
could easily contain very malicious software such as deleting
hard drive. There are ways to prevent this, but not worth the effort.
Reply
#6
(Feb-25-2018, 03:57 AM)kiyoshi7 Wrote: since the string in the textbox will be easy to access and also I don't really like the idea of dynamically importing things since the file can be changed while the program is running
There must be some missing context in your question. Are you executing the variable contents of a GUI's text box? Even in this case, it is not a good idea to exec the code in a function's local namespace. You can execute the code in a dictionary or in a new module's dict
import types
mod = types.ModuleType('Spam')
mod.Pt = self.Pt
exec(mystring, mod.__dict__)
Reply
#7
Quote:here must be some missing context in your question. Are you executing the variable contents of a GUI's text box?
in the text box I am basically programming in python. I have given up on the idea of having a simple text editor in my program it's going to be to much work for little to no return. I have a menu bar where I can select the file I want my program to execute(so I have the file's path and name), but I can't figure out how to import it without getting the same error. Gribouillis, I don't understand how or what to do what I want from your code.
to summarize all I want to do is in runtime select a python file, click a button, have the script run and updating matplotlib
Reply
#8
Quote:I have given up on the idea of having a simple text editor in my program it's going to be to much work
Just an FYI
There is a complete text editor contained in the book 'Tkinter GUI applications Development': https://ebooks-it.org/1849697949-ebook.htm
Reply
#9
Quote:ust an FYI
There is a complete text editor contained in the book 'Tkinter GUI applications Development': https://ebooks-it.org/1849697949-ebook.htm
thanks I'll take a look at it, but after I am able to 'import' a file and run it within my class, somehow
Reply
#10
Here's a simple example of imorting classes

run this way:
python prog1.py
prog1.py
import prog2

class prog1:
    def __init__(self):
        self.second = prog2.prog2()

    def method1(self, index):
        print(self.second.get_item(index))

    def method2(self, index):
        print(self.second.alist[index])

if __name__ == '__main__':
    pg = prog1()
    pg.method1(2)
    pg.method2(0)
prog2.py
class prog2:
    def __init__(self):
        self.alist = ['item1', 'item2', 'item3', 'item4']

    def get_item(self, idx):
        retval = None
        if idx < len(self.alist):
            retval = self.alist[idx]
        return retval
running prog1 results in:
Output:
item3 item1
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  How to avoid exec(), globals(), locals(), eval() paul18fr 10 4,906 Apr-21-2021, 05:53 PM
Last Post: snippsat
  exec in a function paul18fr 6 3,308 Apr-19-2021, 11:10 AM
Last Post: paul18fr
  exec + subprocess = UnboundLocalError paul18fr 6 3,445 Feb-04-2021, 06:27 AM
Last Post: Gribouillis
  exec() in class, NameError niski1996 6 3,874 Apr-20-2020, 07:14 PM
Last Post: niski1996
  Is this use of exec pythonic? psolar 1 1,799 Feb-07-2020, 12:23 PM
Last Post: buran
  problem using exec to save local variables dkarl 0 1,762 Dec-01-2019, 08:52 AM
Last Post: dkarl
  common code, def a function vs exec() a string Skaperen 7 3,269 May-27-2019, 10:13 AM
Last Post: heiner55
  namespaces in comprehension in exec() Skaperen 4 4,642 Mar-28-2017, 03:31 AM
Last Post: Skaperen

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020