Dunderless Python = Python -Dunder Methods

Dunderless Python = Python -Dunder Methods

Dunderless Python = Python -Dunder Methods will help you pick the best way to write concise and correct software without slowing down your code when working with Python. There are multiple options like using namedtuples, data classes, and Attrs.

This story is about improving your code quality and ways to reduce boilerplate when working with python. There are multiple options like using namedtuples, data classes, and Attrs. In this article, I will help you choose one!

Dunderless Python = Python -Dunder Methods

We All Love Python

Python is one of the programming languages I use the most. I started using it mostly for CTFs (for the fantastic pwntools framework) and ended up using it whenever possible.

We all love Python, but even Python got some pitfalls.

Double underscore should be pronounced “dunder”. So init is “dunder init dunder”, or just “dunder init”. — Ned Batchelder

The main issues I see with Python are:

  • When doing OOP, separating logic into multiple subclasses is very tedious as you need to make classes and define dunder methods for each of them. That usually pushed me away from applying SRP to gain time.
  • When you have complex data that need to be expressed, make the mistake of using the language data structures, and you will end up with some code that looks like this data["results_tweets"].get("hits", [])[3][USER_ID]. Even If you define custom classes, you will be writing a lot of boilerplate code and initialization logic anyway.
  • Using data structures like List and Dict is very easy, so we end up using them everywhere. That makes the job very hard for your team to figure out what values are inside (especially if you don’t use type hints).

As it turns out to be, solving all these issues breaks down to improving a simple task: Creating a class or a data container in an easy and straightforward way, which means without boilerplate or effort to write or read object protocols (init = under under init under under).

This article will help you pick the best way to write concise and correct software without slowing down your code.

Let’s Make Your Python Perfect

If you want to fight like a Ninja, you need to pick a Katana and master its fighting art to perfection. The same applies for Python. You need to choose good methods and tools and master them in order to write high-quality code.

Use-case

I came up with a simple use-case of data modeling. We will start by implementing it using a basic Python data structure and then working on it to understand the challenges and improve our implementation.

Company X sells business laptops. It sells to companies like Company P. Employees of company P can buy the laptops with a 50% reduction. Company X needs to access personal information about company P employees E (like their credit cards CC information).

It can also be described with this Diagram, if you prefer visuals:

Image for post

Diagram by Author.

Lists, Tuples and Dicts

Python makes it very easy and convenient to use its data-structures (not like cpp, for instance). So people tend to overuse them.

Let’s try to model our use-case with only basic data structures:

P = {"name": "Doodle", 
     "employees": [{"name":"john doe", 
                    "credit_cards":[("Master Card","4111111111111111", 543),
                                    ("Master Card","4111111111211111", 523),
                                    ("Master Card","4111111311111111", 143)]}]}

C = {"name": "MBI", "clients": [P], 
     "laptops":[{"label":"Dell XPS", "price":2000, "price_unit":"USD"}]}

Let’s try to print the credit card pins for john doe :

#print john doe credit cards security pins
for client in C.get('clients'):
  for employee in client.get('employees'):
    if (employee.get('name') == "john doe"):
      for credit_card in employee.get('credit_cards'):
        print(credit_card[2])

Let’s also try to collect the credit card pins as a List :

#get john_doe credit cards security pins
john_doe = [client.get('employees') for client in C.get('clients') if employee.get('name') == "john doe"][0]
pins = [credit_card[2] for credit_card in  john_doe[0].get('credit_cards')]
print(john_doe)
print(pins)

Although our data model is quite simple, we can already see how this implementation is pushing for bad coding practices:

  • Readability: [credit_card[2] for credit_card in john_doe[0].get('credit_cards')] is not my definition of readable code, even if very readable language like Python. Those accessing methods are not scalable and become harder and harder to read if your model gets extended.
  • Extension: As the credit card model is implemented using a Tuple. We are using an index to access the values (like credit_card[2]). Suppose you change the tuple by adding or removing fields. You will need to change the access index to it everywhere, and the same rule applies if you use unpacking.
  • Side effects: In this example, we used dicts and lists to model higher concepts like company and employee and their relationships. Beware that lists and dictionaries are mutable. By design, they describe values that can be added and removed and not fixed ones. There are more suitable alternatives to model fixed fields 👊.

Using data structures should be limited to relationships. It can also be a_ good idea if the concept is a perfect fit for a data structure_, and you don’t need any particular behaviour, just the data container.

For example, you can use pairs to model rational numbers as a denominator and numerator pair. It fits if you are not planning to do any special operations with them. If your needs change and you need to implement multiplication, for example. You can switch to a class representation.

data-science programming python developer

Bootstrap 5 Complete Course with Examples

Bootstrap 5 Tutorial - Bootstrap 5 Crash Course for Beginners

Nest.JS Tutorial for Beginners

Hello Vue 3: A First Look at Vue 3 and the Composition API

Building a simple Applications with Vue 3

Deno Crash Course: Explore Deno and Create a full REST API with Deno

How to Build a Real-time Chat App with Deno and WebSockets

Convert HTML to Markdown Online

HTML entity encoder decoder Online

Basic Data Types in Python | Python Web Development For Beginners

In the programming world, Data types play an important role. Each Variable is stored in different data types and responsible for various functions. Python had two different objects, and They are mutable and immutable objects.

Hire Python Developers

Are you looking for experienced, reliable, and qualified Python developers? If yes, you have reached the right place. At **[HourlyDeveloper.io](https://hourlydeveloper.io/ "HourlyDeveloper.io")**, our full-stack Python development services...

Applied Data Science with Python Certification Training Course -IgmGuru

Master Applied Data Science with Python and get noticed by the top Hiring Companies with IgmGuru's Data Science with Python Certification Program. Enroll Now

Hire Python Developers India

Looking to build robust, scalable, and dynamic responsive websites and applications in Python? At **[HourlyDeveloper.io](https://hourlydeveloper.io/ "HourlyDeveloper.io")**, we constantly endeavor to give you exactly what you need. If you need to...

Data Science With Python | Python For Data Science | Data Science For Beginners

This Data Science with Python Tutorial will help you understand what is Data Science, basics of Python for data analysis, why learn Python, how to install Python, Python libraries for data analysis, exploratory analysis using Pandas, introduction to series and dataframe, loan prediction problem, data wrangling using Pandas, building a predictive model using Scikit-Learn and implementing logistic regression model using Python.