110

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

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
Shades88
  • 7,934
  • 22
  • 88
  • 130
  • Would post the complete error with the callstack? – sloth Jul 27 '12 at 10:33
  • could you please add the code how you're calling? – Babu Jul 27 '12 at 10:33
  • 2
    Is there some code missing. This snippet works fien for me. – ThirdOne Jul 27 '12 at 10:34
  • 2
    I am extremely sorry. Yes my indentation was duped. Totally newbie in python. So might have missed on the criticality of indentation. – Shades88 Jul 27 '12 at 11:06
  • while coding Python, you should choose "Show tabs and spaces" in your code editor – vanduc1102 Jun 28 '16 at 16:37
  • I think for me it was a case of adding a method to a subclass - and forgetting to do it on the base class. Then when an instance of the base class was invoked the method wasn't there to execute – JGFMK May 16 '21 at 19:07
  • 1
    This should be duped to [I'm getting an IndentationError. How do I solve it?](https://stackoverflow.com/questions/45621722), as the issue is an otherwise non-reproducible problem with indentation and that is the canonical for such. However, the title is then completely inappropriate to act as a signpost. This question is **completely unhelpful for the overwhelming majority of people** who get this error message and is thus doing harm; it should be deleted. However, there are currently many questions **wrongly** closed as a duplicate of this (they are different problems). – Karl Knechtel Mar 26 '23 at 04:42
  • ...So we really need a new canonical done from scratch. – Karl Knechtel Mar 26 '23 at 04:44

9 Answers9

123

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

Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
38

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.

Community
  • 1
  • 1
Timothy Mugayi
  • 1,449
  • 17
  • 11
  • Is it documented in a PIP? – dashesy May 01 '20 at 23:12
  • 3
    just run into the issue and found this comment, why would they design it so? – neurothew Jul 20 '20 at 07:44
  • 3
    It is documented here : https://docs.python.org/3/tutorial/classes.html#private-variables – Mohit Nov 24 '20 at 11:15
  • 1
    I'm debugging with Spyder, and if I call a private class function during execution it's happy; but try to supply it to a selector as a callback parameter and it barfs. I never had this happen with Python2. So very frustrating. – PfunnyGuy Jun 24 '22 at 22:13
19

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.

Trevor
  • 1,858
  • 4
  • 21
  • 28
  • 3
    I know I am five years late to the game but do you know of a solution to this issue? – djo Jul 08 '22 at 18:47
13

This may also occur when using __slots__ for a class which do not mention the desired attribute. For example:

class xyz(object):
    __slots__ = ['abc', 'ijk']
    def __init__(self):
       self.abc = 1
       self.ijk = 2
       self.pqr = 6

Trying to create an instance fails:

>>> xyz()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 6, in __init__
AttributeError: 'xyz' object has no attribute 'pqr'
Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
Mitendra
  • 1,426
  • 17
  • 11
2

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.

Shital Shah
  • 63,284
  • 17
  • 238
  • 185
1

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

Maifee Ul Asad
  • 3,992
  • 6
  • 38
  • 86
Shyam Gupta
  • 489
  • 4
  • 8
0

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

0

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

Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140
remobob
  • 9
  • 2
-3

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.

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • 4
    The author isn't trying to access a private method, the question is also more than 6 years old and already solved so there's no need to trying to answer it again. – Johan Sep 25 '18 at 15:38