NameError: name 'self' is not defined after using eval() - python-3.x

I am trying to save some copy-paste while defining my buttons and other things in my main class through eval(). I know eval() is supposed to be handled with care, but here I give the commands within my code. Here's the code that creates an error:
class MyApp(QMainWindow):
def __init__(self):
[...]
Schaltpunkte=["Aussen1","Innen1","Innen2","Innen","Alle"]
for Schaltpunkt in Schaltpunkte:
eval("self.ui.Button_"+Schaltpunkt+"Laden.clicked.connect(lambda: self.ladeZeitschaltung("+Schaltpunkt+"))")
The error I get once I clicked the button:
Traceback (most recent call last):
File "<string>", line 1, in <lambda>
NameError: name 'self' is not defined
I had this idea, because eval() works very well inside another function:
Programm = eval("self.ui.Box_"+Schaltpunkt+"Programm.value()")
Does someone have any advice? Or is it simply wrong to connect buttons with actions through such code? Thanks for your help!

Your lambda function is not aware of self.
Try to define a symbol table mentioning self, and give it to eval():
symbols = {"self": self}
eval("lambda x: self.foo(x)", symbols)

Related

Python script works fine independently, however, when called from an external script, I get NameError name 'x' is not defined

So basically, I am learning Python (therefore I am new, so be gentle lol). I work in IT and wanted to make a program that has all the basic stuff that I do everyday.
The main program opens up and shows a few options for tools and such. I wanted to add a To Do List to the options.
When my To Do list is called the GUI will appear, however, whenever the buttons are clicked, I get the NameError. I assume the main program just doesn't understand the defined functions that I have assigned to the buttons on the To Do list.
I am curious as to why. Of course I would love a solution, however, I am genuinely curious and interested as to why the interpreter doesn't see or "understand" the defined functions.
I called the To Do List using
toDoBtn = tk.Button(self, text = "To Do List",
command=lambda: exec(open("ToDo.py").read()))
The error I get is
Traceback (most recent call last):
File "C:\Users\brannon.harper\AppData\Local\Programs\Python\Python37\lib\tkinter\__init__.py", line 1705, in __call__
return self.func(*args)
File "<string>", line 49, in insertTask
NameError: name 'inputError' is not defined
I will add the beggining part of ToDo.py, however, I feel as if the issue is how I am calling the script, not how the script is written.
from tkinter import *
from tkinter import messagebox
tasks_list = []
counter = 1
# Function for checking input error when
# empty input is given in task field
def inputError() :
if enterTaskField.get() == "" :
messagebox.showerror("Input Error")
return 0
return 1
The ToDo.py script ends with
if __name__ == "__main__" :
# create a GUI window
gui = Tk()
#### I just design the GUI here.
#### After it is designed It ends with
gui.mainloop()
Thanks so much for your time, and this is my first post, so if I did something wrong or didn't follow the "standard entry" please correct me and let me know for the future!
The function inputError isn't defined because exec can't perform any operation that would bind local variables such as importing, assigning variables, or function/class definitions etc.
This is explained more in this SO post, or in the documentation here

what is wrong with calling the help function?

I have problems calling the help function on the pd.read_csv()
pandas is already imported as pd
import pandas as pd
help(pd.read_csv())
and I get
Traceback (most recent call last):
File "<pyshell#21>", line 1, in <module>
help(pd.read_csv())
TypeError: parser_f() missing 1 required positional argument: 'filepath_or_buffer'
What is wrong with my help call?
in help(pd.read_csv()) you first called pd.read_csv() (cause of the parenthesis) so the interpreter was expecting an argument for, to execute it and return its result and pass it as argument to help.
The help function accepts functions as arguments so to show help execute help(pd.read_csv).
pd.read_csv is the function, pd.read_csv() is a call to that function.
Quite simply: don't call the object you want help on. Here:
help(pd.read_csv())
The parents after pd.read_csv are the function call operator. You don't want to call this function, you want to pass it as argument to help(), ie:
help(pd.read_csv)

How to add a new method to an existing import in python? Specifically moviepy

For whatever reason, Python is not allowing me to access a custom method I created in moviepy's preview.py file. I just want to know how to correctly implement it into the file. For reference, before I changed the name of the method, it was working correctly.
I checked at least two __init.py__ files and they were effectively empty. I couldn't find if methods are initialized anywhere, and is probably what I'm missing.
I also tried restarting Git Bash and that didn't work either (another solution I saw).
Original:
#convert_masks_to_RGB
def preview(clip, fps=15, audio=True, audio_fps=22050, audio_buffersize=3000,
audio_nbytes=2, fullscreen=False):
Changed:
#requires_duration
#convert_masks_to_RGB
def preview_custom(clip, marker_overlay="marker_overlay.png", fps=15, audio=True, audio_fps=22050, audio_buffersize=3000,
audio_nbytes=2, fullscreen=False):
There are more than a few differences between the changed and original method, however at the moment the only result I expect is having the method be called correctly. Error is below:
Traceback (most recent call last):
File "T3AJM.py", line 249, in <module>
main()
File "T3AJM.py", line 34, in main
GUI_main_menu()
File "T3AJM.py", line 85, in GUI_main_menu
GUI_play_markers()
File "T3AJM.py", line 125, in GUI_play_markers
video.preview_custom(marker_overlay=TEMP_OVERLAY_FILE)
AttributeError: 'VideoFileClip' object has no attribute 'preview_custom'
Thank you for your time.
I'm not even sure if this technically fixes the problem, but just doing:
from moviepy.video.io.preview import *
and
preview_custom(video, marker_overlay=TEMP_OVERLAY_FILE)
fixed the problem. I have no idea why I had to change the way it was called, as doing clip.preview(), or in this case video.preview() worked perfectly fine before, but whatever.

Avoiding order dependency in typed python

I am playing with typed python. It's mostly working well but I am having
to reorder a lot of my code because of order dependencies. For example
consider this toy code:
from typing import ClassVar, List
class MyFirstClass:
attr: MyClass
class MyClass:
# You can optionally declare instance variables in the class body
attr: int
class MySecondClass:
attr: MyClass
This fails to compile properly because MyClass is not declared
in MyFirstClass:
Traceback (most recent call last):
File "Temp.py", line 5, in <module>
class MyFirstClass:
File "Temp.py", line 6, in MyFirstClass
attr: MyClass
NameError: name 'MyClass' is not defined
Irritating. Is there anyway around this? Am I doing something wrong?
The best I have come up with so far as defining MyClass twice, first
time with no body.
The way around it is a future-import:
from __future__ import annotations
This causes Python to not evaluate the annotations at runtime and instead just attaches them to __annotations__ as strings.
This change is described in PEP 563 - Postponed evaluation of annotations. Do note that it requires Python 3.7+.

python modify builtin string functions

is it possible in Python to modify, or - at least - deny of execution builtin functions? I need, for educational purpose, to make sure that strings split is unavailable.
For example, I want, if call
'a,b,c'.split(',')
to throw exception or be returned inputed string.
I want to force someone to write own version of that function. Is it possible?
Thanks in advance!
Built-in types (str in your case) and methods cannot be monkey-patched, since they are implemented in C (for cpython implementation).
However, you can define a subclass and redefine the method:
>>> class Mystr(str):
... def split(self, *args):
... raise Exception("Split is not defined")
...
>>> Mystr("test").split(",")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in split
Exception: Split is not defined

Resources