Reputation: 21
I have the following error:
Error Traceback (most recent call last): line 25,line 14,line 3 AttributeError: 'str' object has no attribute 'Teamname'
Here is my python code:
class Team:
def __init__(self,Name = "Name",Origin= "india"):
self.Teamname = Name
self.Teamorigin= Origin
def DefTeamname(self,Name):
self.Teamname = Name
def defTeamorigin(self,Origin):
self.Teamorigin = Origin
class Player(Team):
def __init__(self,Pname,Ppoints,Tname,Torigin):
Team.__init__(Tname,Torigin)
self.Playername = Pname
self.Playerpoints = Ppoints
def Scoredpoint(self):
self.Playerpoints += 1
def __str__(self):
return self.Playername + "has scored" + str(self.Playerpoints) + "points"
Player1 = Player('Sid',0,'Gokulam','Kochi')
print(Player1)
What am I doing wrong?
Upvotes: 0
Views: 64
Reputation: 5964
Your error is being thrown because the first argument to __init__
is being interpreted as self
, and __init__
is therefore trying to mutate it. It only works at all because you use keyword arguments, so Origin
is just falling back to the default.
Note for completeness that you can call the method directly on the target class (or any other class for that matter), but that self
is not bound and you lose the advantage of super()
always pointing to the parent in the MRO. This works:
class A:
def __init__(self, a):
self._a = a
class B:
def __init__(self, a, b):
self._b = b
A.__init__(self, a)
b = B(6, 7)
assert b._a == 6
Incidentally this shows that __init__
is just a function which takes a muteable first arg (self
by convention) and mutates that arg.
You really should use super()
however. What happens if I redefine A?:
class newA:
def __init__(self):
self._other = True
class A(newA):
...
If you have used super()
all the way through, everything will work fine:
class NewA:
def __init__(self, **kwargs):
super().__init__(**kwargs)
class A(NewA):
def __init__(self, a=None, **kwargs):
self._a = a
super().__init__(**kwargs)
Note the use of keyword arguments to pass up the chain without worrying about the semantics of every class's init.
Python's super considered harmful for warnings about how things can go wrong if you don't keep your semantics compatible.
Upvotes: 2
Reputation: 2471
class Player(Team):
def __init__(self,Pname,Ppoints,Tname,Torigin):
super().__init__(Tname,Torigin)
...
You cannot call __init__
yourself on the class, you need to call on the instance by using super()
notation, else the self
parameter will not be bound correctly
Upvotes: 1