How to I manipulate a value in a class in Python?

Question:

So i’am new into classes in python, and i was struggling a little bit here :(. So I wanted to make a class point which contained coordinates (x, y). First I made a function which set the values and afterwards a function to print the values in a tuple. But then i wanted to manipulate the y coordinate to reflect along the x-axis. But suddenly it started to give me an AttributeError

Input:

class Point:
  def __init__(self, x, y):
      self.x = x
      self.y = y

  def print(self):
      i = (self.x, self.y)
      print(tuple(i))

  def reflect_x(self):
      self.y*=-1

p1 = Point(1,4)
p1.print()

p2 = Point(-3,5)
p2.print()

p3 = Point(-3,-5)
p3.reflect_x().print()

Output:

(1, 4)
(-3, 5)
Traceback (most recent call last):
  File "/I'd/love/to/keep/this/private/Oef.py", line 22, in <module>
    p3.reflect_x().print()
AttributeError: 'NoneType' object has no attribute 'print'

As you can se as long as i don’t implement my reflect_x function I don’t get an error.

My wish-to output:

(1, -4)
(-3, -5)
(-3, 5)

Thank you in advance <3

Asked By: SiBMs

||

Answers:

Apply it directly to the object:

p3 = Point(-3,-5)
p3.reflect_x()
p3.print()

As opposed to the result of reflect_x(), which doesn’t return anything.

Answered By: Tanner

it seems like you are trying to print the state of your p3 Object after calling reflect_x, right?

For that I would suggest to use p3.print() below your last line like you did before. You cannot call print that way, because it is trying to find it as a function of what reflect_x returns, which is None, and not you Class.

Answered By: Marc Leibold

As it was already pointed out, reflect_x() returns default value (None), since you didn’t put any return there. If you are used to the programming language that endorses chaining methods, you should add return self in functions you wanna use like that.

class Point:
  def __init__(self, x, y):
      self.x = x
      self.y = y

  def print(self):
      i = (self.x, self.y)
      print(tuple(i))
      return self # change here

  def reflect_x(self):
      self.y*=-1
      return self # change here

p1 = Point(1,4)
p1.print()

p2 = Point(-3,5)
p2.print()

p3 = Point(-3,-5)
p3.reflect_x().print()

therefore allowing your methods to be chainable. A nice video about it.

Answered By: Andrew Menshicov

Yeah it’s quite simple. When you call the p3.reflect_x().print(), it means you call the print() function from the p3.reflect_x() object. But the p3.reflect_x() means the object return from reflect_x() function of p3 object. And here it is None because you dont return any thing from your code.
So you just add the return in reflect_x() function and it will work. It will look like this:

def reflect_x(self):
      self.y*=-1
      return self
Answered By: mxnthng
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.