Using instances from other classes, overriding and

2019-09-11 09:51发布

问题:

First of all thank you for taking your time to consider the following inquiry. English is not my main language so I tried to be as clear as I could so I apologize in advance for it.

Considering this code for the questions (keeping in mind that I cannot change any of the code in the class Point):

class Point:

  def __init__(self, xcoord=0, ycoord=0)
      self.x = xcoord
      self.y = ycoord

  def setx(self, xcoord):
      self.x = xcoord

  def sety(self, ycoord):
      self.y = ycoord

  def __repr__(self):
    return 'Point('+str(self.x)+','+str(self.y)+')'

  def __str__(self):
    return 'Point('+str(self.x)+','+str(self.y)+')'

class Figure:

    def __init__(self, bottom_left, top_right):
        Point.__init__(bottom_left)
        Point.__init__(top_right)
        self.bottom_left = bottom_left 
        self.top_right = top_right

    def get_bottom_left(self):
        print(Point().setx(self.bottom_left))
        print (self.bottom_left)

    def get_top_right(self):
        print(self.top_right)

    def __repr__(self):
        return 'Point('+str(self.x)+','+str(self.y)+') + ', Point('+str(self.x)+','+str(self.y)+')'

    def __str__(self):
        return 'Point('+str(self.x)+','+str(self.y)+') + ', Point('+str(self.x)+','+str(self.y)+')'

When assigning

f = Figure(Point(),Point(1,2))

1) To my knowledge, init, repr and str are python methods that by being in a class they modify the object without being called explicitly. So the reason repr and str are in both classes is to be able to get the output "Point(0,0), Point()" when inputing f in the interpreter. But when I try that I get that Figure has no attribute 'x'.

a) I manage to create the x and y values when using a single point directly into the class Point, but I can't seem to do that when doing it through class Figure even though I am initializing bottom_left and top_right in the class Figure, through the class Point by using

Point.init(bottom_left)

In other words, I don't know how to break down Figure(Point(),Point(1,2)) into:

Point() = x = 0, y = 0

Point(1,2) = x = 1, y = 2

Through the use of the first class

2) I don't know how to "override a Python's function" without using Inheritance, is it even possible? By this I am referring to the methods I am using here: init, repr and str.

3) When trying to access function setx() from class Point through the

print(Point().setx(self.bottom_left))

I get the value none. When I put a return (just to test because I can't do this) in setx() it returns Point(0,0) instead of just the x value.

My guess is that I have to use inheritance, but I was suggested to just use instances from class Point.

I usually don't ask this often after another previous post, but I am running out of time at this point and I really want to understand the core of the problem (This is a more simplified version of the actual assignment for me to be able to attack my core misunderstandings which is in general interconnecting values, objects and instances from one class to another).

回答1:

Your first problem comes when re-initialising the points in your Figure class's init method:

    Point.__init__(bottom_left)
    Point.__init__(top_right)

If you check the 'Point' class's init method, it takes in the parameters 'self, xcoord=0, ycoord=0'. So what you are doing is sending in the 'bottom_left' and 'top_right' points as the 'self' parameter, with default values for the x- and y-coordinates. This sets these points' values to 0.

There is no need to call these initialisations; you have already initialised the points when you called Point() and Point(1,2).

To address your concerns:

1) You are working with a Figure object, not a Point object in the Figure repr and str methods. 'Figure' does not have 'x' and 'y' attributes, just 'bottom_left' and 'top_right' (both objects of type Point). So reference these instead.

1a) Addressed above: you do not need to re-initialise the Point objects. You just need to set 'bottom_left' to the entered 'bottom_left' object and the same for 'top_right' (which you are doing).

2) By creating your own repr and str methods in 'Figure', you are overriding the default 'object' class methods, not the 'Point' methods. You can leverage off Point's implementations instead of repeating everything though. eg:

def __str__(self):
    return str(self.bottom_left) + ', ' + str(self.top_right)

3) Examine the method parameters of setx(). What does it expect? Hint: not a Point object!



回答2:

Firstly, you have a few syntax errors in your code:

def __init__(self, xcoord=0, ycoord=0)

is missing a : at the end.

return 'Point('+str(self.x)+','+str(self.y)+') + ', Point('+str(self.x)+','+str(self.y)+')'
return 'Point('+str(self.x)+','+str(self.y)+') + ', Point('+str(self.x)+','+str(self.y)+')'

have missing or extra ' in them.

1) Yes, those methods change how the class instance is created and represented. __str__ and __repr__ are failing because when they're called (when you try to print that instance) the code under those two methods is failing. Looks like you want to return the value of the point's coordinates, more like this:

def __repr__(self):
    return 'Point(' + str(self.bottom_left.x) + ',' + str(self.bottom_left.y) + '), ' + 'Point(' + str(self.top_right.x) + ',' + str(self.top_right.y) + ')'

def __str__(self):
    return 'Point(' + str(self.bottom_left.x) + ',' + str(self.bottom_left.y) + '), ' + 'Point(' + str(self.top_right.x) + ',' + str(self.top_right.y) + ')'

a) You don't need to explicitly call Point.__init__ in your Figure __init__ method; that happens already when you pass it Point().

2) Not quite sure what you mean here, not sure how else you'd do it without overriding these methods.

3) Here you are not printing Point() after it's had setx called; you're printing the return of setx. None is what is returned from any Python function that doesn't explicitly return something. Your setx function doesn't have a return, so it returns None. It still works, in that it still sets x. Try:

p = Point()
p.setx(44)
print(p)