-4
class A:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def method(self):
        return A(self.x + 1, self.y + 1)

    def method2(self, f):
        if self.f().x > 3:
            return True

a = A(1, 2)
y = a.method2(a.method())
print(y)

The error occurs on the line with

if self.f().x > 3:

I don't understand why it says it has no attribute and not method.

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
adil.a
  • 9
  • 4
  • 2
    Because a method *is* an attribute. Why did you think `self.f()` *would* work? – jonrsharpe Jan 11 '20 at 22:37
  • I was writing this code to help with my understanding of OOP. I thought it would work because self.f() would refer to self.method() which then returns a new class and I wanted to access this class's 'x' instance attribute. – adil.a Jan 11 '20 at 22:40
  • 2
    It's unclear why you thought: 1. Accessing `A.f` would give you the attribute of A with the name of the *value* of f (see https://stackoverflow.com/q/2612610/3001761); or 2. The value of `a.method()` would be `"method"`. – jonrsharpe Jan 11 '20 at 22:42
  • Why would the value of ```a.method()``` be "method" if it returns a new class? – adil.a Jan 11 '20 at 22:47
  • 2
    Well, exactly, so... why would f in that method be a value that meant self.f was self.method?! Even if self.f did magically use the value of f, that doesn't make sense. Your expectations seem totally irrational to me. – jonrsharpe Jan 11 '20 at 22:48
  • I’m voting to close this. It’s a matter of understanding Classes/methods/whatever, and is unlikely to be useful to anyone else. – AMC Jan 12 '20 at 03:25
  • Please don’t call a method “method”, by the way, it complicates things needlessly. – AMC Jan 12 '20 at 03:27

2 Answers2

0

Let's go through the call to a.method2.

  1. You call a.method(). This returns a new instance of A
  2. This new instance is passed to a.method2 as the local variable f
  3. You then attempt to call a.f (through self), but f is an instance

You aren't calling self.<some_function>, you are trying to say that an instance of A has an attribute that is also an instance of A, which is not the case. It's effectively doing:

a.A(a.x+1, a.y+1).x

Which raises your error. Yes, an instance of A has the attribute x, but no instance of A has an attribute matching this new instance. It's not totally clear what you are trying to accomplish. If you are trying to test the value of the attribute on a new instance, you might just do:

class A:
    def __init__(self, x
        self.y = y

    def method(self):
        return A(self.x + 1, self.y + 1)

    def method2(self):
        # just check the value itself
        if self.x > 3:
            return True
        else:
            return False

a = A(1, 2)

# b is a new instance, you shouldn't be testing values of b
# via some function in a, because really this function
# exists in all instances, including b
b = a.method()

# so check b.x through the instance b instead
b.method2()
False
C.Nivs
  • 12,353
  • 2
  • 19
  • 44
  • Thank you for taking the time to answer this, stack overflow can be incredibly harsh to new programmers... I guess basic questions shouldn't go on here – adil.a Jan 12 '20 at 05:02
  • There are lots of basic questions on here. Sometimes, questions look like they are asking for one thing, when really the root of the issue is what the actual goal of the program is. That's why there were lots of *what are you trying to do* questions. We've all started somewhere, and we've all created our own ball of spaghetti code. I remember my first question on here, which is how I learned that asking the internet for help can be a bit jarring. Keep improving, keep learning, and don't be afraid of basic questions. Usually someone has asked them before. Happy coding :) – C.Nivs Jan 12 '20 at 19:26
0

The problem relies just on mixing "self." and "f()". What method() returns and method2() should expect is a class object, so you just have to use it exactly as that.

This way it perfectly works:

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

    def method(self):
        return A(self.x + 1,  self.y + 1)

    def method2(self, f):
        return f.x > 3

a = A(1, 2)
y = a.method2(a.method())
print(y)
Kalma
  • 111
  • 2
  • 15