In this exercise, the __add__() method is implemented for the Atom class but returns a Molecule class. Does __add__() always need to return a different class?
Answer
NO. The __add__() method can be implemented to return whatever type or class makes sense for the operation. For this exercise, the addition of two Atom objects returns a Molecule. In some other case, a class may just return a new instance of the same class. The __add__() method is free to return whatever makes sense for the operation being performed.
Is that a question. Could you be a bit more specific?
The bottom line is that the + operator is defined fairly intuitively for both numbers and strings, but if youâd like to somehow make use of it in another context, the __add__ method provides a way for you to do so.
Iâm no expert either but i agree with you. You get the same answer as SOLUTION using this code. Also, this code is similar to the example that we are shown in the lesson add.
The idea behind the dunder method, __add__() is so we donât have to call on the method explicitly. Just using the + (plus sign) is enough to invoke it.
I modified code a bit and it now returns Nacl which make more sense . instead of Atoms address
class Atom:
def __init__(self, label):
self.label = label
def __add__(self, other):
return Molecule([self.label, other.label])
class Molecule:
def __init__(self, atoms):
if type(atoms) is list:
self.atoms = atoms
def __repr__(self): #now I see how usefull repr method could be
sum = ''
for atom in self.atoms:
for char in atom:
sum += char
return sum
sodium = Atom("Na")
chlorine = Atom("Cl")
print(sodium + chlorine) # return Nacl Instead of original code returns <__main__.Atom object at 0x7f3cce61e780>, <__main__.Atom object at 0x7f3cce61e9e8>]
The interpreter sees the + operator between two Atom objects so looks for an __add__() method on their instance. It takes the first in the expression as self and the other, which is also an instance, as other. We see above they are not really added, nor even concatenated, just written into a Molecule instance as a list of Atom instances. That instance is then returned. Now we are able to represent that object instance with its __repr__() method.
Aside
The Molecule instance is just a list of Atom objects, each with a label attribute. Below we unpack on the assumption the molecule is a compound of just two atoms:
def __repr__(self):
a, b = self.atoms # unpack
return f"{a.label}{b.label}" # return formatted string
Of course it wonât be much good for compounds of more than two elements so iteration will be needed. We wonât need to iterate over characters, though, just the atoms attributeâŠ
def __repr__(self):
s = ""
for x in self.atoms:
s += x.label
return s
link
can you help me to understand why my example does not work?
class Atom:
def __init__(self, label):
self.label = label
def __add__(self, other):
return Molecule([self.label, other.label])
def __repr__(self):
return self.label
class Molecule:
def __init__(self, atoms):
if type(atoms) is list:
self.atoms = atoms
def __repr__(self):
#a, b = self.atoms # unpack
#return f"{a.label}{b.label}" # return formatted string
s = ""
for x in self.atoms:
s += x.label
return s
sodium = Atom("Na")
chlorine = Atom("Cl")
#salt = Molecule([sodium, chlorine])
salt = sodium + chlorine
print(sodium) # Na
print(salt) # NaCl
print(salt.atoms) # ['Na', 'Cl']
print(salt.atoms[0]) # Na
console log:
Traceback (most recent call last):
File "script.py", line 28, in <module>
print(salt) # NaCl
File "script.py", line 18, in __repr__
s += x.label
AttributeError: 'str' object has no attribute 'label'
Not sure how Molecule being returned in Atom is related to Molecule class created below it, how does one not cancel the other out and how do they relate to each other
class Atom:
def __init__(self, label):
self.label = label
def __add__(self, other):
return Molecule([self, other])
class Molecule:
def __init__(self, atoms):
if type(atoms) is list:
self.atoms = atoms
sodium = Atom("Na")
chlorine = Atom("Cl")
salt = sodium + chlorine
print (Molecule(salt))
# salt = sodium + chlorine