为什么会出现AttributeError:对象没有属性[关闭]


81

我有一个类MyThread。在那我有一个方法示例。我试图从相同的对象上下文中运行它。请看一下代码:

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()

看起来很简单,不是吗。但是当我运行它时,我得到这个错误

AttributeError: 'myThread' object has no attribute 'sample'现在,我就在那里使用该方法。那怎么了 请帮忙

编辑:这是堆栈跟踪

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'

我这样称呼它

arThreads = []
maxThreads = 2;

for i in range( maxThreads ):
    redisOpsObj = redisOps()
    arThreads.append( myThread(i, "Thread-"+str(i), 10, redisOpsObj) )

抱歉,我无法发布redisOps类代码。但我可以向您保证,它的效果很好


会在调用堆栈中发布完整的错误吗?
懒惰

您能添加代码吗?
巴布(Babu)2012年

2
是否缺少一些代码。此代码段对我有效。
ThirdOne'7

2
非常抱歉 是的,我的缩进被骗了。完全是python的新手。因此,可能已经错过了缩进的重要性。
Shades88

在对Python进行编码时,应在代码编辑器中选择“显示制表符和空格”
vanduc1102

Answers:


92

您的缩进已弄糟,并且您混用了制表符和空格。运行脚本python -tt进行验证。


感谢您的大开眼界。现在明白了。抱歉,您的问题太愚蠢,解释时间太长;)
Shades88

3
您能否告诉我“使用python -tt运行脚本进行验证”的含义是什么?
akshay_rahar

9
@akshay_rahar:python -tt script.py
Ignacio Vazquez-Abrams

1
那么,这个魔术参数有-tt什么作用?我还没有找到它的文档
卢卡斯Nojek

8
更新:-tt标志在Python 3中不存在,在Python 2中存在。
ŁukaszNojek '19

12

这些错误在Python多线程处理中很常见。发生的结果是,在解译器拆除后,相关模块(myThread在这种情况下)经历了排序del myThread

该电话self.sample()大致等于myThread.__dict__["sample"](self)。但是,如果我们在解释器的拆解序列中,则它自己的已知类型字典可能已经myThread删除了,现在基本上是NoneType-,并且没有'sample'属性。


11

如果您使用的是python 3+,则在使用以双下划线开头的私有变量(例如self .__ yourvariable)时,也会发生这种情况。对于可能遇到此问题的一些人来说,这只是要注意的事情。


它记录在PIP中吗?
破事

1
刚遇到问题并找到此评论,他们为什么会这样设计?
matthewhang

7

如果您在类中使用插槽并且尚未在插槽中添加此新属性,则也可能会发生这种情况。

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'

2

对于多线程方案(特别是在处理ZMQ时),出现此错误。原来,套接字仍在一个线程上,而另一个线程已经开始发送数据。由于另一个线程而发生的事件试图访问尚未创建的变量。如果您的方案涉及多线程,并且如果您添加一点延迟,那么如果一切正常,那么您可能会有类似的问题。


1

Python通过内部更改名称以包括类名称来保护这些成员。您可以访问诸如object._className__attrName之类的属性。


0

我也遇到了相同的错误。我确定我的缩进没有任何问题。仅重启python sell解决了该问题。


您可以发布命令以重新启动或执行任何操作。这可能对初学者有所帮助。

0

当我有另一个名为mythread的变量时,发生了相同的错误。这个变量覆盖了这个,这就是为什么我得到错误


-3

您无法访问课程的私有字段以外的内容。私有字段以__开头。例如 -

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是私有方法。


2
作者没有尝试访问私有方法,该问题也已有6年以上的历史了,已经解决了,因此无需尝试再次回答。
约翰
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.