1

Relatively new Python programmer here. So I am trying to create a variable that is accessible and changeable by any method within a class that is initialized within the constructor. So far, I cannot figure out how to do this.

As sort of a "band-aid" to the problem, I've been using 'self' before every variable in the class. Surely, there is another way.

For instance:

class Image:
    height, width = 0,0

    def __init__(self, heightInput, widthInput, pixelValue):
        height = heightInput
        width = widthInput

    def readHeight:
        print(height)

testObj = Image(10, 10, 20)
testObj.readHeight()

I would expect the output to be "10", yet instead an error is thrown that 'height' is not a variable. I have many more questions similar to this, however in essence I would like to know if there is any way I can avoid using the "self" word so much. Thanks!

Blorgbeard
  • 101,031
  • 48
  • 228
  • 272
  • 2
    "As sort of a "band-aid" to the problem, I've been using 'self' before every variable in the class. Surely, there is another way." No, there isn't. You must use `self` – juanpa.arrivillaga Jul 15 '19 at 21:31
  • `self` isn't a band-aid solution. It is literally the only way to distinguish between the class attribute and a global variable with the same name – Adarsh Chavakula Jul 15 '19 at 21:32
  • You just made `height`, `width` local variables to `__init__` method. You should read how OOP works. – heemayl Jul 15 '19 at 21:32
  • Yes, I understand that. "the only way to distinguish between the class attribute and a global variable with the same name" well my question is that, should I have a unique global variable (declared outside a method), how do I access it from within a method? For instance, how would I access the class-variables of width and height? THAT is my issue. – Grey Aycock Jul 15 '19 at 21:50
  • @GreyAycock yes, you already have the answer, you use `self.my_var` – juanpa.arrivillaga Jul 15 '19 at 22:17

2 Answers2

3

height and width are classic variables which will only live in your __init__ method, to solve that, you have to use self.height and self.width instead. self points to the current object and this is the way to bind something to it.

EDIT: You should read some articles about Python OOP, there a few things unique to this language. For example, a Python class has 1 constructor __new__ and 1 initializer __init__. The 1st one is really a constructor because the instance does not exist yet when you go into it, its return value is mostly the needed instance. Then Python automatically calls the __init__ method of the object returned by the constructor and it's where you build your instance attributes. Of course, you could bind attributes directly from __new__ but __init__ is here for that.

Shizzen83
  • 3,325
  • 3
  • 12
  • 32
  • lol beat me to it. – SkippyNBS Jul 15 '19 at 21:31
  • Well yes, that's what I've been doing, however I wanted to know if there was any other way of doing this. Surely not all Python programs are littered with countless "self"s, right? – Grey Aycock Jul 15 '19 at 21:36
  • Yes they are, unlike languages like C# where they're not enforced – Shizzen83 Jul 15 '19 at 21:39
  • Also, what then is the point of having the height and width variables declared outside of any methods? Do they just serve as final ints? – Grey Aycock Jul 15 '19 at 21:39
  • I edited my answer to add some explanations – Shizzen83 Jul 15 '19 at 21:46
  • Ahhh Python OOP is so much more confusing than Java! Can you try to answer my other question I just asked in the comments? Thank you for your help so far! – Grey Aycock Jul 15 '19 at 21:55
  • Declaring some variables outside of any methods binds them to the class itself. They're accessible from any instance of the class. The most common use-case is an instances counter: initialized to 0 and incremented in `__init__` – Shizzen83 Jul 15 '19 at 22:06
  • @GreyAycock no, that is not a variable declaration. *Python doesn't have variable declarations*, those are two *class level*, i.e. *static* variables that you will shadow with instance variables. just remove that line. Python != Java – juanpa.arrivillaga Jul 15 '19 at 22:18
  • Thank you everyone for bearing with me. I suppose my wording wasn't concise enough, because I found my answer in the use of just saying Image.height = heightInput . That was the piece I was looking for - how to manipulate a class variable. Edit: You can also use self. I'm just an idiot - I'm sorry. Thank you again, everyone. – Grey Aycock Jul 15 '19 at 22:33
1

As Shizzen83 said, self refers to the instance of the class object. So any variable that's going to be used throughout the class needs to start with 'self.'

def __init__(self, heightInput, widthInput, pixelValue):
    self.height = heightInput
    self.width = widthInput

def readHeight:
    print(self.height)

That's what you're looking for.

Amir Almusawi
  • 354
  • 2
  • 7