Overview

How long have you been at this?! This time, let's straighten out Mirori's spirit, who tarnishes the name of Pythonistas with such whiny complaints.

 

What's All Mixed Up?

Well, it's about this↓...

  • In Python classes, when you define instance variables, you do it inside __init__ with self., right? That's fine.
  • In JavaScript, sometimes you see instance variables defined outside the constructor. Well, that's just how it works, and it's okay. But can you do the same in Python, “define instance variables outside the constructor”? I'm not sure...
  • When you define a variable outside the constructor (__init__) in Python, doesn't it become a class variable that can be freely modified outside the class? Conversely, is that possible in JavaScript?

 

Python and Node.js Versions Used in This Note

python -V
# --> Python 3.10.12

node -v
# --> v20.11.0

 

Public “Class Variables” Accessible from Outside the Class

In Python.

class MyObject:
    foo = 'Foo.'

print(MyObject.foo)
# --> Foo.

In JS.

class MyObject {
  static foo = 'Foo.'
}

console.info(MyObject.foo)
// --> Foo.

 

“Class Variables” Accessible Only Within the Class (private) -

In Python. If you ask a Pythonista, they might say it's possible to mess with these from outside the class, but that's a hack (mangling)! And it looks better if you use @classmethod, but that's just a Pythonista's preference.

class MyObject:
    __foo = 'Foo.'

    def main():
        print(MyObject.__foo)
        # --> Foo.

MyObject.main()
print(MyObject.__foo)
# --> AttributeError: type object 'MyObject' has no attribute '__foo'

In JS.

class MyObject {
  static #foo = 'Foo.'

  static main() {
    console.info(MyObject.#foo)
    // --> Foo.
  }
}

MyObject.main()
console.info(MyObject.#foo)
// --> SyntaxError: Private field '#foo' must be declared in an enclosing class

 

Public “Instance Variables” Accessible from Outside the Class

In Python.

class MyObject:
    def __init__(self):
        self.foo = 'Foo.'

my_object = MyObject()
print(my_object.foo)
# --> Foo.

In JS. The most confusing part for me is right here.

  • It's confusing that you can define them either outside or inside the constructor.
  • The appearance of defining them outside the constructor looks the same as Python's public class variables, which is confusing.
class MyObject {
  foo = 'Foo.'

  constructor() {
      // You can define it here too!!
      this.foo = 'Foo.'
  }
}

const myObject = new MyObject()
console.info(myObject.foo)
// --> Foo.

 

“Instance Variables” Accessible Only Within the Class (private)

In Python.

class MyObject:
    def __init__(self):
        self.__foo = 'Foo.'

    def main(self):
        print(self.__foo)
        # --> Foo.

my_object = MyObject()
my_object.main()
print(my_object.__foo)
# --> AttributeError: 'MyObject' object has no attribute '__foo'

In JS.

class MyObject {
  #foo = 'Foo.'

  constructor() {
      // You can define it here too!!
      this.#foo = 'Foo.'
  }

  main() {
    console.info(this.#foo)
    // --> Foo.
  }
}

const myObject = new MyObject()
myObject.main()
console.info(myObject.#foo)
// --> SyntaxError: Private field '#foo' must be declared in an enclosing class

 

Did We Clear Up the Confusion?

  • Can you also “define instance variables outside the constructor” in Python?: No, you cannot. In Python, only those with self. are instance variables. It's clear! Python wins!
  • When you define a variable outside the constructor (__init__) in Python, doesn't it become a class variable that can be freely modified outside the class?: Exactly.
  • Conversely, is that possible in JavaScript?: Yes, it is possible. In JavaScript, class variables are defined with `static

`, and they can be freely modified from outside the class.

JavaScript ends up with more markers (in this case, static) due to being able to define both class and instance variables outside the constructor, which detracts from its simplicity. (If, like in Python, the definition area for instance variables was limited to inside methods, then marking with static outside the constructor would be unnecessary.)

 

Key Points

  • When you want to create public fields, neither Python nor JavaScript requires anything special.
  • When you want to create private fields, prefix the variable with __ in Python and # in JavaScript.
  • When you want to create class variables, Python requires nothing special, whereas JavaScript requires static.
  • When you want to create instance variables, define them with self. inside the constructor in Python, and define them directly under the class without static or inside the constructor with this. in JavaScript.

Organizing it like this is fun, isn't it?