Mastering Python Functions: Write Them Like This or Get Your Pull Request Rejected!

Mastering Python Functions: Write Them Like This or Get Your Pull Request Rejected!

This is the approach we followed at work, and I’m fully on board with it.

The Way We Were Taught to Write Python Functions

Here’s a basic function:

  • It takes in a list of numbers num_list and a number num
  • It adds num to each element in num_list
  • It returns a new list

def add_all(num_list, num):
    output = []
    for n in num_list:
        output.append(n + num)
    return output

x = add_all([3, 4, 5], 10)
print(x)  # Output: [13, 14, 15]        

The Problem

At first glance, this function doesn’t tell us:

  • What data types it accepts.
  • What data type it returns.

Sure, after reading the code, we can guess that num_list is a list of numbers, and num is a number, but it’s not immediately clear. In a production-grade app with thousands of functions, wasting time on such guesses adds up.

Type Annotations to the Rescue

This is where type annotations (also called type hints) come in handy. Let’s improve the function by adding them.

from typing import List, Union

def add_all(
    num_list: List[Union[int, float]], 
    num: Union[int, float]
) -> List[Union[int, float]]:
    """
    Adds a number to each element in a list.

    Args:
        num_list: A list of numbers (integers or floats).
        num: A number (integer or float).

    Returns:
        A new list with num added to each element.
    """
    output = [n + num for n in num_list]
    return output

x: List[Union[int, float]] = add_all([3, 4, 5], 10)
print(x)  # Output: [13, 14, 15]        

Breaking it Down

  • Union[int, float] means the variable can be either an integer or a float.
  • List[Union[int, float]] specifies that the list can contain both integers and floats.
  • The docstring at the beginning explains what the function does, making it much easier to understand.

Why Tech Lead Insists on This:

  • You instantly know what data types the function expects and returns.
  • There’s no need to infer or waste time guessing.
  • The docstring provides a clear description of the function’s purpose.
  • This makes the code more readable, maintainable, and scalable.

Common Type Hints

Here’s a quick guide to commonly used type hints:

# Basics:
a: int = 5
b: float = 3.14
c: bool = True
d: str = 'apple'

# Collections:
from typing import List, Dict, Tuple, Set

# List of integers
a: List[int] = [1, 2, 3]

# Dictionary with string keys and integer values
c: Dict[str, int] = {'apple': 4, 'orange': 5}        

You can also use Union for mixed data types:

from typing import Union, Dict

def add10(number: Union[int, float]):
    pass

def test(d: Dict[str, Union[int, float, bool]]):
    pass        

Alternatively, use the cleaner int | float syntax:

def add10(number: int | float):
    pass

def test(d: Dict[str, int | float | bool]):
    pass        

Optional Variables

Sometimes, a variable can be None:

from typing import Optional
from random import random

def test() -> Optional[int]:
    if random() > 0.5:
        return 1000
    return None        

Conclusion

If your code lacks type annotations or docstrings, expect your pull request to get rejected. Clear code is not just good practice — it’s essential for maintainability.

If you wish to support me as a creator

  • Share your thoughts in the comments
  • Buy one of my courses with special discount (contact me on Linkedin for free coupon)

?? Special Offer for My Readers ??

Use code: LEARNWITHME at checkout on Udemy to get 90% off my courses.

The Complete Data Structures and Algorithms in Python

Complete Python Bootcamp For Everyone From Zero to Hero

Python Database Course: SQLite, PostgreSQL, MySQL,SQLAlchemy

Java Data Structures and Algorithms Masterclass


Thank you for your support — it truly means a lot!

Connect with me:

要查看或添加评论,请登录

Elshad Karimov的更多文章

社区洞察

其他会员也浏览了