Python AttributeError when referencing a settings class [duplicate] - python-3.x

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 3 years ago.
This post was edited and submitted for review 1 year ago and failed to reopen the post:
Original close reason(s) were not resolved
Improve this question
I have a class MyThread. In that, I have a method sample. I am trying to run it from within the same object context. Please have a look at the code:
class myThread (threading.Thread):
def __init__(self, threadID, name, counter, redisOpsObj):
threading.Thread.__init__(self)
self.threadID = threadID
self.name = name
self.counter = counter
self.redisOpsObj = redisOpsObj
def stop(self):
self.kill_received = True
def sample(self):
print "Hello"
def run(self):
time.sleep(0.1)
print "\n Starting " + self.name
self.sample()
Looks very simple ain't it. But when I run it I get this error
AttributeError: 'myThread' object has no attribute 'sample' Now I have that method, right there. So what's wrong? Please help
Edit: This is the stack trace
Starting Thread-0
Starting Thread-1
Exception in thread Thread-0:
Traceback (most recent call last):
File "/usr/lib/python2.6/threading.py", line 525, in __bootstrap_inner
self.run()
File "./redisQueueProcessor.py", line 51, in run
self.sample()
AttributeError: 'myThread' object has no attribute 'sample'
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/lib/python2.6/threading.py", line 525, in __bootstrap_inner
self.run()
File "./redisQueueProcessor.py", line 51, in run
self.sample()
AttributeError: 'myThread' object has no attribute 'sample'
I am calling it like this
arThreads = []
maxThreads = 2;
for i in range( maxThreads ):
redisOpsObj = redisOps()
arThreads.append( myThread(i, "Thread-"+str(i), 10, redisOpsObj) )
Sorry, I can't post the redisOps class code. But I can assure you that it works just fine

Your indentation is goofed, and you've mixed tabs and spaces. Run the script with python -tt to verify.

If you’re using python 3+ this may also occur if you’re using private variables that start with double underscore, e.g., self.__yourvariable. Just something to take note of for some of you who may run into this issue.

These kind of bugs are common when Python multi-threading. What happens is that, on interpreter tear-down, the relevant module (myThread in this case) goes through a sort-of del myThread.
The call self.sample() is roughly equivalent to myThread.__dict__["sample"](self).
But if we're during the interpreter's tear-down sequence, then its own dictionary of known types might've already had myThread deleted, and now it's basically a NoneType - and has no 'sample' attribute.

This may also occur if your using slots in class and have not added this new attribute in slots yet.
class xyz(object):
"""
class description
"""
__slots__ = ['abc', 'ijk']
def __init__(self):
self.abc = 1
self.ijk = 2
self.pqr = 6 # This will throw error 'AttributeError: <name_of_class_object> object has no attribute 'pqr'

I got this error for multi-threading scenario (specifically when dealing with ZMQ). It turned out that socket was still being connected on one thread while another thread already started sending data. The events that occured due to another thread tried to access variables that weren't created yet. If your scenario involves multi-threading and if things work if you add bit of delay then you might have similar issue.

Python protects those members by internally changing the name to include the class name.
You can access such attributes as object._className__attrName.

I have encountered the same error as well. I am sure my indentation did not have any problem. Only restarting the python sell solved the problem.

The same error occurred when I had another variable named mythread. That variable overwrote this and that's why I got error

You can't access outside private fields of a class. private fields are starting with __ .
for example -
class car:
def __init__(self):
self.__updatesoftware()
def drive(self):
print("driving")
def __updatesoftware(self):
print("updating software:")
obj = car()
obj.drive()
obj.__updatesoftware() ## here it will throw an error because
__updatesoftware is an private method.

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

attribute error in python Snake game, what does it mean? [duplicate]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 3 years ago.
This post was edited and submitted for review 1 year ago and failed to reopen the post:
Original close reason(s) were not resolved
Improve this question
I have a class MyThread. In that, I have a method sample. I am trying to run it from within the same object context. Please have a look at the code:
class myThread (threading.Thread):
def __init__(self, threadID, name, counter, redisOpsObj):
threading.Thread.__init__(self)
self.threadID = threadID
self.name = name
self.counter = counter
self.redisOpsObj = redisOpsObj
def stop(self):
self.kill_received = True
def sample(self):
print "Hello"
def run(self):
time.sleep(0.1)
print "\n Starting " + self.name
self.sample()
Looks very simple ain't it. But when I run it I get this error
AttributeError: 'myThread' object has no attribute 'sample' Now I have that method, right there. So what's wrong? Please help
Edit: This is the stack trace
Starting Thread-0
Starting Thread-1
Exception in thread Thread-0:
Traceback (most recent call last):
File "/usr/lib/python2.6/threading.py", line 525, in __bootstrap_inner
self.run()
File "./redisQueueProcessor.py", line 51, in run
self.sample()
AttributeError: 'myThread' object has no attribute 'sample'
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/lib/python2.6/threading.py", line 525, in __bootstrap_inner
self.run()
File "./redisQueueProcessor.py", line 51, in run
self.sample()
AttributeError: 'myThread' object has no attribute 'sample'
I am calling it like this
arThreads = []
maxThreads = 2;
for i in range( maxThreads ):
redisOpsObj = redisOps()
arThreads.append( myThread(i, "Thread-"+str(i), 10, redisOpsObj) )
Sorry, I can't post the redisOps class code. But I can assure you that it works just fine
Your indentation is goofed, and you've mixed tabs and spaces. Run the script with python -tt to verify.
If you’re using python 3+ this may also occur if you’re using private variables that start with double underscore, e.g., self.__yourvariable. Just something to take note of for some of you who may run into this issue.
These kind of bugs are common when Python multi-threading. What happens is that, on interpreter tear-down, the relevant module (myThread in this case) goes through a sort-of del myThread.
The call self.sample() is roughly equivalent to myThread.__dict__["sample"](self).
But if we're during the interpreter's tear-down sequence, then its own dictionary of known types might've already had myThread deleted, and now it's basically a NoneType - and has no 'sample' attribute.
This may also occur if your using slots in class and have not added this new attribute in slots yet.
class xyz(object):
"""
class description
"""
__slots__ = ['abc', 'ijk']
def __init__(self):
self.abc = 1
self.ijk = 2
self.pqr = 6 # This will throw error 'AttributeError: <name_of_class_object> object has no attribute 'pqr'
I got this error for multi-threading scenario (specifically when dealing with ZMQ). It turned out that socket was still being connected on one thread while another thread already started sending data. The events that occured due to another thread tried to access variables that weren't created yet. If your scenario involves multi-threading and if things work if you add bit of delay then you might have similar issue.
Python protects those members by internally changing the name to include the class name.
You can access such attributes as object._className__attrName.
I have encountered the same error as well. I am sure my indentation did not have any problem. Only restarting the python sell solved the problem.
The same error occurred when I had another variable named mythread. That variable overwrote this and that's why I got error
You can't access outside private fields of a class. private fields are starting with __ .
for example -
class car:
def __init__(self):
self.__updatesoftware()
def drive(self):
print("driving")
def __updatesoftware(self):
print("updating software:")
obj = car()
obj.drive()
obj.__updatesoftware() ## here it will throw an error because
__updatesoftware is an private method.

Tkinter objects being garbage collected from the wrong thread

I seem to be breaking tkinter on linux by using some multi-threading. As far as I can see, I am managing to trigger a garbage collection on a thread which is not the main GUI thread. This is causing __del__ to be run on a tk.StringVar instance, which tries to call the tcl stack from the wrong thread, causing chaos on linux.
The code below is the minimal example I've been able to come up with. Notice that I'm not doing any real work with matplotlib, but I can't trigger the problem otherwise. The __del__ method on Widget verifies that the Widget instance is being deleted from the other thread. Typical output is:
Running off thread on 140653207140096
Being deleted... <__main__.Widget object .!widget2> 140653210118576
Thread is 140653207140096
... (omitted stack from from `matplotlib`
File "/nfs/see-fs-02_users/matmdpd/anaconda3/lib/python3.6/site-packages/matplotlib/text.py", line 218, in __init__
elif is_string_like(fontproperties):
File "/nfs/see-fs-02_users/matmdpd/anaconda3/lib/python3.6/site-packages/matplotlib/cbook.py", line 693, in is_string_like
obj + ''
File "tk_threading.py", line 27, in __del__
traceback.print_stack()
...
Exception ignored in: <bound method Variable.__del__ of <tkinter.StringVar object at 0x7fec60a02ac8>>
Traceback (most recent call last):
File "/nfs/see-fs-02_users/matmdpd/anaconda3/lib/python3.6/tkinter/__init__.py", line 335, in __del__
if self._tk.getboolean(self._tk.call("info", "exists", self._name)):
_tkinter.TclError: out of stack space (infinite loop?)
By modifying the tkinter library code, I can verify that __del__ is being called from the same place as Widget.__del__.
Is my conclusion here correct? How can I stop this happening??
I really, really want to call matplotlib code from a separate thread, because I need to produce some complex plots which are slow to render, so making them off-thread, generating an image, and then displaying the image in a tk.Canvas widget seemed like an elegant solution.
Minimal example:
import tkinter as tk
import traceback
import threading
import matplotlib
matplotlib.use('Agg')
import matplotlib.figure as figure
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
class Widget(tk.Frame):
def __init__(self, parent):
super().__init__(parent)
self.var = tk.StringVar()
#tk.Entry(self, textvariable=self.var).grid()
self._thing = tk.Frame(self)
def task():
print("Running off thread on", threading.get_ident())
fig = figure.Figure(figsize=(5,5))
FigureCanvas(fig)
fig.add_subplot(1,1,1)
print("All done off thread...")
#import gc
#gc.collect()
threading.Thread(target=task).start()
def __del__(self):
print("Being deleted...", self.__repr__(), id(self))
print("Thread is", threading.get_ident())
traceback.print_stack()
root = tk.Tk()
frame = Widget(root)
frame.grid(row=1, column=0)
def click():
global frame
frame.destroy()
frame = Widget(root)
frame.grid(row=1, column=0)
tk.Button(root, text="Click me", command=click).grid(row=0, column=0)
root.mainloop()
Notice that in the example, I don't need the tk.Entry widget. However if I comment out the line self._thing = tk.Frame(self) then I cannot recreate the problem! I don't understand this...
If I uncomment then gc lines, then also the problem goes away (which fits with my conclusion...)
Update: This seem to work the same way on Windows. tkinter on Windows seems more tolerant of being called on the "wrong" thread, so I don't get the _tkinter.TclError exception. But I can see the __del__ destructor being called on the non-main thread.
I had exactly the same problem
It was a nightmare to find the cause of the issue. I exaustivelly verified that no tkinter object was being called from any thread. I made a mechanism based in queues to handle tkinter objects in threads.
There are many examples on the web on how to do that, or... search for a module 'mttkinter', a thread safe wrapper for Tkinter)
In a effort to force garbage collection, I used the "gc" method in the exit function of every TopLevel window of my App.
#garbage collector
import gc
...
gc.collect()
but for some reason, closing a toplevel window continued to reproduce the problem. Anyway... it was precisely using some prints in the aforementioned "mttkinter" module that I detected that, in spite the widgets are being created in the main thread, they could be garbage collected when garbage collector is triggered inside another thread. It looks like that the garbage collector gathers all the garbage without any distinction of its provenience (mainthread or other threads?). Someone please correct me if I'm wrong.
My solution was to call the garbage collector explicitly using the queue as well.
PutInQueue(gc.collect)
Where "PutInQueue" belongs to a module created by me to handle tkinter object and other kind of objects with thread safety.
Hope this report can be of great usefullness to someone or, it it is the case, to expose any eventual bug in garbage collector.
Tkinter is not thread safe. Calling Tkinter objects in a thread may cause things such as "The del method on Widget verifies that the Widget instance is being deleted from the other thread."
You can use locking and queues to make it done properly.
Check this example:
Tkinter: How to use threads to preventing main event loop from "freezing"
and this example (there are many many other examples you can find):
Mutli-threading python with Tkinter
Hope this will put you in the right direction.

Multiprocessing does not see global variables?

I have run into a strange behaviour at multiprocessing.
When i try to use a global variable in a function which is called from multiprocessing it does not see a global variable.
Example:
import multiprocessing
def func(useless_variable):
print(variable)
useless_list = [1,2,3,4,5,6]
p = multiprocessing.Pool(processes=multiprocessing.cpu_count())
variable = "asd"
func(useless_list)
for x in p.imap_unordered(func, useless_list):
pass
Output:
asd
multiprocessing.pool.RemoteTraceback:
"""
Traceback (most recent call last):
File "/usr/lib/python3.4/multiprocessing/pool.py", line 119, in worker
result = (True, func(*args, **kwds))
File "pywork/asd.py", line 4, in func
print(variable)
NameError: name 'variable' is not defined
"""
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "pywork/asd.py", line 11, in <module>
for x in p.imap_unordered(func, useless_list):
File "/usr/lib/python3.4/multiprocessing/pool.py", line 689, in next
raise value
NameError: name 'variable' is not defined
As you see the first time i just simply call func it print asd as expected. However when i call the very same function with multiprocessing it says the variable variable does not exists, even after i clearly printed it just before.
Does multiprocessing ignore global variables? How can i work this around?
multiprocessing Pools fork (or spawn in a way intended to mimic forking on Windows) its worker processes at the moment the Pool is created. forking maps the parent memory as copy-on-write in the children, but it doesn't create a persistent tie between them; after the fork, changes made in the parent are not visible in the children, and vice versa. You can't use any variables defined after the Pool was created, and changes made to variables from before the Pool was created will not be reflected in the workers.
Typically, with a Pool, you want to avoid mutable global state entirely; have all the data needed passed to the function you're imap-ing (or whatever) as arguments (which are serialized and sent to the children, so the state is correct), and have the function return any new data instead of mutating globals, which serializes it and sends it back to the parent process to use as it sees fit.
Managerss are an option, but not usually the correct option with Pools; you usually want to stick to workers only looking at read only globals from before the Pool was created, or working with arguments and returning new values, not using global state at all.
When you spam a process all context is copyed, you need to get use of managers for exachanging objects between them, check the official documentations, for managing state check this.

Class wrapper around file -- proper way to close file handle when no longer referenced

I've got a class that wraps some file handling functionality I need. Another class creates an instance of the filehandler and uses it for an indeterminate amount of time. Eventually, the caller is destroyed, which destroys the only reference to the filehandler.
What is the best way to have the filehandler close the file?
I currently use __del__(self) but after seeing several different questions and articles, I'm under the impression this is considered a bad thing.
class fileHandler:
def __init__(self, dbf):
self.logger = logging.getLogger('fileHandler')
self.thefile = open(dbf, 'rb')
def __del__(self):
self.thefile.close()
That's the relevent bit of the handler. The whole point of the class is to abstract away details of working with the underlying file object, and also to avoid reading the entire file into memory unnecessarily. However, part of handling the underlying file is closing it when the object falls out of scope.
The caller is not supposed to know or care about the details involved in the filehandler. It is the filehandler's job to release any necessary resources involved when it falls out of scope. That's one of the reasons it was abstracted in the first place. So, I seem to be faced with moving the filehandler code into the calling object, or dealing with a leaky abstraction.
Thoughts?
__del__ is not, by itself, a bad thing. You just have to be extra careful to not create reference cycles in objects that have __del__ defined. If you do find yourself needing to create cycles (parent refers to child which refers back to parent) then you will want to use the weakref module.
So, __del__ is okay, just be wary of cylic references.
Garbage collection: The important point here is that when an object goes out of scope, it can be garbage collected, and in fact, it will be garbage collected... but when? There is no guarantee on the when, and different Python implementations have different characteristics in this area. So for managing resources, you are better off being explicit and either adding .close() on your filehandler or, if your usage is compatible, adding __enter__ and __exit__ methods.
The __enter__ and __exit__ methods are described here. One really nice thing about them is that __exit__ is called even when exceptions occur, so you can count or your resources being closed gracefully.
Your code, enhanced for __enter__/__exit__:
class fileHandler:
def __init__(self, dbf):
self.logger = logging.getLogger('fileHandler')
self.thefilename = dbf
def __enter__(self):
self.thefile = open(self.thefilename, 'rb')
return self
def __exit__(self, *args):
self.thefile.close()
Note that the file is being opened in __enter__ instead of __init__ -- this allows you to create the filehandler object once, and then use it whenever you need to in a with without recreating it:
fh = filehandler('some_dbf')
with fh:
#file is now opened
#do some stuff
#file is now closed
#blah blah
#need the file again, so
with fh:
# file is open again, do some stuff with it
#etc, etc
As you've written it the class doesn't make the file close any more reliably. If you simple drop the filehandler instance on the floor then the file won't close until the object is destroyed. This might be immediately or might not be until the object is garbage collected, but just dropping a plain file object on the floor would close it just as quickly. If the only reference to thefile is from inside your class object then when filehandler is garbage collected thefile will be also be garbage collected and therefore closed at the same time.
The correct way to use files is to use the with statement:
with open(dbf, 'rb') as thefile:
do_something_with(thefile)
that will guarantee that thefile is always closed whenever the with clause exits. If you want to wrap your file inside another object you can do that too by defining __enter__ and __exit__ methods:
class FileHandler:
def __init__(self, dbf):
self.logger = logging.getLogger('fileHandler')
self.thefile = open(dbf, 'rb')
def __enter__(self):
return self
def __exit__(self, exc_type, exc_value, traceback):
self.thefile.close()
and then you can do:
with FileHandler(dbf) as fh:
do_something_with(fh)
and be sure the file gets closed promptly.

Resources