Question

Firstly, know that I QUADRUPLE CHECKED my identation.

Here are my sources:

--MyClass.py--

class MyClass:
    def __init__(self, a,b):
        self.A = a
        self.B = b
    def __setattr__(self,name,value):
        print self
        print "setting value of " + name + " to " + str(value)
    def myTest(self):
        print self
        print "testing the value of self.A" + str(self.A)

-- test.py --

from MyClass import MyClass
aClass=MyClass(1,2)
aClass.myTest()

The only other file I have on this directory is an empty __init__.py

I have a very simple test program that imports MyClass and tries to use it by calling only one method: myTest(). I'm getting this attribute error because of MyClass

I'm running this on ubuntu linux with python 2.7.5+, tried also on the raspberry pi with raspbmc, and on Mac too with same results.

user@machine:~$ python -tt test.py 
<MyClass.MyClass instance at 0xb746426c>
setting value of A to 1
<MyClass.MyClass instance at 0xb746426c>
setting value of B to 2
<MyClass.MyClass instance at 0xb746426c>
Traceback (most recent call last):
  File "test.py", line 4, in <module>
    aClass.myTest()
  File "/home/user/MyClass.py", line 11, in myTest
    print "testing the value of self.A" + str(self.A)
AttributeError: MyClass instance has no attribute 'A'
Was it helpful?

Solution

You've overridden the __setattr__ method, but you are not setting any attribute inside it:

def __setattr__(self,name,value):
    print self
    print "setting value of " + name + " to " + str(value)
    object.__setattr__(self, name, value)

And don't forget make your class inherit from object to make it a new-style class.

class MyClass(object):
    def __init__(self, a,b):
    ...

In old-style classes to set an attribute you need to use self.__dict__, for new-style classes object.__setattr__(...) is the recommended way.:

self.__dict__[name] = value

OTHER TIPS

Your __setattr__ is responsible to set the attributes of the instance, but isn't doing anything except printing some messages. When you re-implement __setattr__ you must write the code that sets the attributes, python doesn't automatically calls the original implementation. Change it to:

def __setattr__(self,name,value):
    print self
    print "setting value of " + name + " to " + str(value)
    self.__dict__[name] = value

Note that, since you are using python2, it would be better to inherit from object:

class MyClass(object):

And then use the parent-class __setattr__ method to do the work:

def __setattr__(self,name,value):
    print self
    print "setting value of " + name + " to " + str(value)
    super(MyClass, self).__setattr__(name, value)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top