Reputation: 10499
I have a Person
class and a SubPerson
sub-class:
class Person:
def setname(self, name):
self.name = name
def display(self):
print(self.name)
class SubPerson(Person):
def display(self):
print("Name: {0}".format(self.name))
if __name__ == "__main__":
p = SubPerson()
p.display()
But when I call the display method of p
I have the following error:
File "./person.py", line 14, in display
print("Name: {0}".format(self.name))
AttributeError: SubPerson instance has no attribute 'name'
Why? How can I fix this?
Upvotes: 2
Views: 160
Reputation: 58281
Why?
You should read exception message: "AttributeError: SubPerson instance has no attribute 'name'
", that clearly indicates that SubPerson
's instance p
that you have created in main using expression p = SubPerson()
don't have attribute 'name'
- that is why it throws AttributeError
exception.
Lets try your code on active interpreter and see:
>>> class Person:
... def setname(self, name):
... self.name = name
... def display(self):
... print(self.name)
...
>>> class SubPerson(Person):
... def display(self):
... print("Name: {0}".format(self.name))
...
>>> p = SubPerson()
>>> p.name # Notice
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: SubPerson instance has no attribute 'name'
>>>
Notice line p.name
- you are getting same exception! Indeed p
has no attribute with name 'name'
you can use introspection technique to list all attribute of p
using __dict__
and inherited attributes using dir()
function, see below
>>> p.__dict__
{} # p don't have it any it own attribute
>>> dir(p) # either don't inerited attribute 'name'
['__doc__', '__module__', 'display', 'setname']
>>>
Notice only the attributes that p
inherits from Person class are 'display', 'setname' but not name
.
How can I fix this?
You have few techniques to rectify your code as below:
Python is dynamic language you can explicitly add new name in object namespace as:
>>> p.name = "grijesh"
>>> p.__dict__ # Now `p` has 'name' attributes
{'name': 'grijesh'}
>>> p.display() # it is safe to call display
Name: grijesh
Use your setname
function as @Tasawer Nawaz's answer suggestion.
Use __init__
function and implement object constructor as give in @T.C.'s answer.
Basically in all technique you are attaching 'name'
attribute to SubPerson instance object before accessing it in display()
function method.
Upvotes: 1
Reputation: 1505
class Person:
def __init__(self, name=""):
self.name=name
#def setname(self, name):
# self.name = name
#instead of display
def __str__(self):
return self.name
#def display(self):
# print(self.name)
if __name__=='__main__':
p=Person("YourName")
print p
You have to "initialize" your attribute of your Person object.. And i would implement the str method to print your objects its like in C++ std::operator<<
..
And your subclass looks like this:
class SubPerson(Person):
def __str__(self):
return "Name: {0}".format(self.name)
There are some other methods(len,get, and so on..), which you can overwrite for your own Class..
Upvotes: 4
Reputation: 925
please set "name" first
p.setname("your_name")
or if you dont want to set name, then initialize name attribute in parent class
class Person:
name = "your_name"
Upvotes: 1