Explain Codes LogoExplain Codes Logo

Determine the type of an object?

python
type-checking
duck-typing
best-practices
Alex KataevbyAlex Kataev·Aug 12, 2024
TLDR

To check an object's type, utilize type(obj). If you need to confirm a type or a subclass, employ isinstance(obj, class).

type([1, 2, 3]) # <class 'list'>. I like lists as much as free food! isinstance([1, 2, 3], list) # True, just like unicorns are true.

101 Understanding of Python type checks

To determine an object's type in Python, you have to ask the object (politely):

  • Is it a certain type or subclass? Use the isinstance(obj, class) function.
  • Or precisely what is the class? Deploy type(obj) for a strict identity check.

Python has versatility to spare, allowing you to check against multiple types:

isinstance(obj, (int, list)) # True if obj is an int or list, but not a bit listy!

When you want to be certain of the exact class of an object, turn to type(). It's the perfect tool for debugging or when the subclass gets too nosey:

type(obj) is int # True, provided obj has not ducked out and is precisely an int.

Advanced Python type checking: Duck typing and ABCs

An alternative approach to cling to Python's duck typing concept. If it walks like a duck, then it's a duck. Let's focus on behavior over hard-coded type:

if hasattr(obj, 'walk'): obj.walk()

For a more formal approach, isinstance() can check against Abstract Base Classes (ABCs) such as Iterable:

from collections import Iterable isinstance(obj, Iterable) # True if object is list, set, tuple, or a walking duck.

Calling on Python's EAFP approach

Instead of overthinking the type checks, embrace Python's "Easier to Ask for Forgiveness than Permission" (EAFP) style and dance a bit with exceptions:

try: result = obj + ' baked beans' # who doesn't like beans? except TypeError: print("Don't mix objects with beans. TypeError alert!")

Additionally, although rarely used and somewhat unruly, there is also obj.__class__. Use it wisely to avoid chaos, and make sure you know your way around multiple inheritance.

A tale of passports and objects

Visualise determining an object's type in Python akin to a passport control:

<img src="https://github.com/someimage.png" alt="Object at Homeland Security">

The type() function acts like a passport officer, revealing the true identity of the object:

type(🧳) # Especially handy when the object is a suitcase full of methods.

Now, with identity (int, list, str, etc.) received, the object proceeds:

🧳: I am a `list`! 📋 🚨: Proceed with list operations. ✔️

Deep dive into Python type checks: Best practices and pitfalls

Python's type checks: type() vs. isinstance()

Choosing between the two often comes down to context. Use type() when you care about strict type equality. On the other hand, if you value the broader family of inheritance, use isinstance().

Mind the pitfalls!

While Python's type checks are handy, they need careful management:

  • Don't get over-attached to type checks; they can make code brittle and less flexible.
  • The false negatives when using type() instead of isinstance() can trip you up.
  • Think about compatibility issues when contemplating using .__class__.

Credits to Python: Type hints and Static Analysis

Python introduced type hints, allowing expected input and return types to be documented:

def greet(name: str) -> None: # Just trying to make future debuggers happy. print(f"Hello, {name}!")

These annotations do not enforce types, but they are an excellent guide for third-party tools offering static type checking like mypy.

Pro Tips for Python type checking

Here are some tricks to write better code with Python type checks:

  • Implement custom type checking using __getattr__ and __setattr__.
  • Embrace duck typing; object behavior can be more valuable than strict typing.
  • Consider built-in Python functions or pythonic idioms before falling for the allure of the complex type checking.