Membership And Instance Operators in Python (vs JavaScript)

Python For JavaScript Developers is a series of side-by-side comparisons between Python and JavaScript. In this episode: membership and instance operators in Python (vs JavaScript).

Python For JavaScript Developers: Membership And Instance Operators

So, you’ve been developing with JavaScript since forever and now you want to approach Python, but don’t know where to start? This series is for you. In this episode you’ll learn how Python compares to JavaScript when it comes to membership and instance operators. Enjoy!

Python For JavaScript Developers: requirements

To follow along you need at least a basic understanding of JavaScript and its quirks. This series is not an exhaustive guide to both languages, rather, a 10.000 feet comparison between them.

You can try the code examples for JavaScript in a browsers’s console or in the Node.js REPL. For Python you can use the Python REPL. Every time you see “>>>” in the code examples, that’s the Python REPL.

The complete series

Missed an episode? Here we go:

The membership operator in Python and JavaScript

“Is this element present inside another element”? Membership operators know the answer. Both Python and JavaScript have a membership operator called in:

PYTHONJAVASCRIPT
inin

In Python you can use in on almost every data type. For example you can check if a character appears inside a string:

>>> "o" in "Florence"

# Output: True

It works for lists, tuples, and dictionaries as well:

>>> my_list = ["vale", 98, "caty", None]
>>> 98 in my_list # Output: True

>>> my_tuple = ("vale", "Italy", 105)
>>> "italy" in my_tuple # Output: False

my_dict = {
    "name": "John", 
    "city": "Rome", 
    "age": 44
    }

"age" in my_dict # Output: True

In JavaScript instead the in operator does not work intuitively neither on strings, nor on arrays:

"a" in ["a", "b", "c"]
// output: false

"o" in "Florence"
// output: TypeError: Cannot use 'in' operator to search for 'o' in Florence

It’s useless for strings, and does not search for actual elements in the array. What it looks for instead is the array index:

1 in ["a", "b", "c"]
// output: true

It makes sense considering that Array is a subtype of Object and it’s more correct to imagine it as an object with the following shape:

var myArr = {
  0: "a",
  1: "b",
  2: "c"
};

To recap, in in JavaScript works only on object keys and returns true if the given key is present in the object:

var my_obj = {"name": "John", "city": "Rome", "age": 44}

"name" in my_obj

// output: true

Instance operators: a disclaimer

“Who created this object”? Instance operators try to answer that question. Now, before you yell at me let me clarify. The following table is just my mental representation of a more complicated story:

PYTHONJAVASCRIPT
isinstance()instanceof
type()typeof

As you’ll see it’s impossible to map Python and JavaScript 1 to 1 on this matter because Python is truly object oriented, while JavaScript is based on prototypes.

If you know a bit of JavaScript you’re aware that “class” is an illusion and every time we talk about classes in JavaScript we’re just lying.

But let’s demystify my table with some examples.

Python classes, isinstance, and JavaScript instanceof

Consider a Python class with a new object made from it:

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def print_details(self):
        details = f"Name: {self.name} - Age: {self.age}"
        print(details)


tom = Person("Tom", 89)

tom.print_details()

What is tom? In object oriented programming we say that it’s a class instance, that is, a new object constructed from the class blueprint. isinstance in Python (it’s a function more than an operator) returns true if an object appears to be built by a given class. So in our case:

>>> isinstance(tom, Person)

# Output: True

How about JavaScript instead? Here’s the same class:

class Person {

    constructor(name, age) {
        this.name = name
        this.age = age
    }

    printDetails() {
        const details = `Name: ${this.name} - Age: ${this.age}`
        console.log(details)
    }

}

const tom = new Person("Tom", 44)

What is tom now? Let’s see:

console.log(tom instanceof Person)
// Output: true

An instance!? Not at all. tom is just a poor object connected to Person.prototype via the prototype chain.

In fact it is also connected to Object:

console.log(tom instanceof Object)
// Output: true

So the instanceof operator in JavaScript returns true if an object appears to be built by a given class, but not because it’s an instance in the strict term. It returns true only because tom is connected to Person.prototype via the prototype chain.

I tried to compare instance operators for both languages and that’s the best I could come up with. I consider Python’s isinstance() and JavaScript instanceof similar just because of how they behave, but it’s still an hazardous comparison.

If so you might wonder, why bringing isinstance() in at all? That leads use to the next section …

Python type() and JavaScript typeof

Anytime you want to inspect the type of a given value in JavaScript, typeof is your friend. It’s an operator, not a function. Here’s an example:

typeof "alex" // "string"
typeof 9 // "number"
typeof [1,2] // "object"

typeof in JavaScript is useful when we want to check if a function exists, for example:

if (typeof window.futureStuff === "undefined") {
    window.futureStuff = function () {
        // do stuff    
    }
}

Coming from JavaScript you may want to reach for a similar operator in Python. The type() function might be your first pick because seems related to JavaScript’s typeof. But type() returns something different:

>>> type(tom)
# Output: <class 'person.Person'>

>>> type('ahh')
# Output: <class 'str'>

Not so convenient. isinstance() is better suited for this job here and that’s why I brought it in the previous section. Here’s how it works:

>>> isinstance(9, int)
# Output: True

>>> isinstance(tom, Person)
# Output: True

>>> isinstance("caty", str)
# Output: True

isinstance() happens to be useful when you need to check a value against another known type. However there might be situation where you need to mimic typeof. In that case you can still use Python’s type function, but this time by accessing the __name__ attribute:

>>> type(9).__name__
# Output: 'int'

Membership And Instance Operators: wrapping up

Python’s isinstance() might look similar to JavaScript’s instanceof, yet they differ substantially.

isinstance() thinks in terms of classes and instances while instanceof does a simple check on the JavaScript prototype chain. isinstance() is also handy for checking the type of a Python object.

Python’s type() function returns the type of any Python object as well, but it’s not so user-friendly, unless you reach for the __name__ attribute. Worth noting, isinstance() and type() are functions, opposed to JavaScript operators typeof and instanceof.

Thanks for reading and stay tuned for more!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.