#DailyPythonTip
Python Tip #311 (of 365):

Make directories with parents and exist_ok. 🧵

Like this:
pathlib.Path("reports/2026").mkdir(parents=True, exist_ok=True)

#Python #DailyPythonTip
November 8, 2026 at 5:26 AM
Python Tip #312 (of 365):

Use the "utf-8-sig" encoding for CSV files. 🧵

Many CSV files start with an invisible byte order mark (BOM).

When read as "utf-8", the first column name starts with a UTF-8 BOM character:

>>> rows[0]
{'\ufeffdate': '2026-10-01', 'kwh': '12.5'}

#Python #DailyPythonTip
November 9, 2026 at 12:48 AM
Python Tip #308 (of 365):

Match tuple-like data by shape with match-case. 🧵

>>> point = (3, 4)
>>> match point:
... case (x, y):
... print(f"2D point ({x}, {y})")
... case (x, y, z):
... print(f"3D point ({x}, {y}, {z})")
...
2D point (3, 4)

#Python #DailyPythonTip
November 5, 2026 at 3:22 AM
Python Tip #309 (of 365):

Match dictionaries by their keys with match-case. 🧵

It's handy for JSON from an API: does a response have an error key, or a type key with a specific value?

Without match, that's an if-elif chain of "in" checks, key lookups, and equality checks.

#Python #DailyPythonTip
November 6, 2026 at 4:43 AM
Python Tip #309 (of 365):

Make dataclasses instead of named tuples. 🧵

Do this:
@dataclass
class Room:
name: str
number: int

Not this:
class Room(NamedTuple):
name: str
number: int

#Python #DailyPythonTip
November 3, 2026 at 3:27 PM
Python Tip #310 (of 365):

Match objects by their type and attributes with match-case. 🧵

A class pattern checks an object's type (like isinstance does) and the values of its attributes, capturing attributes into variables.

#Python #DailyPythonTip
Appreciating Python's match-case by parsing Python code
Python's match-case blocks are complex structural pattern matching tools that are often more hassle than they're worth. But they're great for parsing abstract syntax trees.
pym.dev
November 7, 2026 at 4:27 AM
Python Tip #306 (of 365):

Don't use tuples for list-like data. 🧵

Do this:
colors = ["pink", "purple", "green", "blue"]

Not this:
colors = ("pink", "purple", "green", "blue")

#Python #DailyPythonTip
November 3, 2026 at 3:58 AM
Python Tip #305 (of 365):

Split only as much as you need with maxsplit. 🧵

Do this:
key, value = line.split("=", maxsplit=1)

Not this:
key, *rest = line.split("=")
value = "=".join(rest)

#Python #DailyPythonTip
November 2, 2026 at 4:46 AM
This has been one of my favorite features of recent Pythons. Can make certain bits much easier to read and much nicer to write.
Python Tip #309 (of 365): Match dictionaries by their keys with match-case. >>> response = {"type": "rectangle", "width": 3, "height": 4} >>> match response: ... case {"type": kind}: ... print(f"Object is {kind}") ... case {"error": message}: ... print(f"Error: {message}") ... case _: ... print("Unknown response") ... Object is rectangle 🧵 (1/3) #Python #DailyPythonTip
mastodon.social
November 7, 2026 at 12:22 AM
Python Tip #303 (of 365):

Remember that strings are iterables of strings. 🧵

Python doesn't have a character type, which usually makes things easier.

If name is a string, name[0] returns a string, and strings have a lower method:

>>> name = "Ada"
>>> name[0].lower()
'a'

#Python #DailyPythonTip
October 30, 2026 at 6:04 PM
Python Tip #302 (of 365):

Use // instead of truncating with int. 🧵

Do this:
mid_point = len(sequence) // 2

Not this:
mid_point = int(len(sequence) / 2)

#Python #DailyPythonTip
October 29, 2026 at 8:54 PM
Python Tip #304 (of 365):

Import the whole module when a name isn't clear. 🧵

Do this:
import random

color = random.choice(colors)

Not this:
from random import choice

color = choice(colors)

#Python #DailyPythonTip
4 ways to import a module in Python
In Python you can import specific variables from a module, you can import the whole module, and you can also rename variables while importing. When should you use each of these import styles?
pym.dev
October 31, 2026 at 6:04 PM
But most Python programmers use "from" imports at least occasionally, if not frequently.

I only use whole-module imports for names that are unclear on their own. For datetime, I import the whole module but rename it to dt (see tip #257).
Trey Hunner (@trey.io)
Python Tip #257 (of 365): Consider "import datetime as dt". 🧵 The fact that the datetime module and the datetime class are spelled the same way is VERY confusing. #Python #DailyPythonTip
bsky.app
October 31, 2026 at 6:04 PM
Python Tip #301 (of 365):

Don't delete "unnecessary" syntax that makes code more readable. 🧵

Some code is unnecessary but NOT unhelpful:

def earliest_date(date1, date2):
if parse(date1) < parse(date2):
return date1
else:
return date2

#Python #DailyPythonTip
Unnecessary else statements
When your function ends in an else block with a return statement in it, should you remove that else?
pym.dev
October 29, 2026 at 3:52 AM
Python Tip #300 (of 365):

Separate the steps of a function with blank lines. 🧵

If you're using an auto-formatter like ruff or Black, you won't have control over most of your whitespace.

But how you use blank lines within functions is still up to you.

#Python #DailyPythonTip
Embrace whitespace
Well placed spaces and line breaks can greatly improve the readability of your Python code.
pym.dev
October 28, 2026 at 3:15 AM
Python Tip #299 (of 365):

Return Boolean expressions directly. 🧵

Do this:
def is_even(n):
return n % 2 == 0

Not this:
def is_even(n):
if n % 2 == 0:
return True
else:
return False

#Python #DailyPythonTip
October 27, 2026 at 2:42 AM
Python Tip #298 (of 365):

When creating lots of class instances, save memory with __slots__. 🧵

class Point:
__slots__ = ("x", "y", "z")

def __init__(self, x, y, z):
(self.x, self.y, self.z) = (x, y, z)

#Python #DailyPythonTip
October 25, 2026 at 3:02 PM
Python Tip #297 (of 365):

Avoid making metaclasses if you can. 🧵

There's usually an easier tool for the job.

Metaclasses customize the behavior of CLASSES the same way classes customize the behavior of their instances.

#Python #DailyPythonTip
October 24, 2026 at 3:03 PM
Python Tip #296 (of 365):

Always use functools.wraps when making a decorator. 🧵

A decorator REPLACES a decorated function with the function that was returned from calling the decorator.

#Python #DailyPythonTip
October 23, 2026 at 3:04 PM
Python Tip #295 (of 365):

Avoid needless deep copying. 🧵

Often a deepcopy call can be replaced by a comprehension, a slice, or some other operation that makes new objects.

When you copy a list of dictionaries, you get a NEW list pointing to the SAME dictionaries.

#Python #DailyPythonTip
October 22, 2026 at 3:03 PM
Python Tip #294 (of 365):

Use exceptions to pass error messages to users. 🧵

Catch exceptions with messages users shouldn't see, and raise your own with a message they SHOULD see:

class WeatherError(Exception):
"""Raised when we can't show the user a forecast."""

#Python #DailyPythonTip
October 21, 2026 at 3:04 PM
Python Tip #293 (of 365):

Write context managers with contextlib.contextmanager. 🧵

Instead of making a class with __enter__ and __exit__ methods, we can make a context manager out of a function:

#Python #DailyPythonTip
October 20, 2026 at 3:03 PM
Python Tip #292 (of 365):

Keep "try" blocks small with an "else" clause. 🧵

try:
count = int(text)
except ValueError:
print("That's not a number")
else:
print(f"Counting to {count}")

#Python #DailyPythonTip
October 19, 2026 at 3:03 PM
Python Tip #291 (of 365):

Check regex matches with the walrus operator. 🧵

Do this:
if match := UNITS_RE‍.search(string):
return match.groups()

Not this:
match = UNITS_RE‍.search(string)
if match:
return match.groups()

#Python #DailyPythonTip
Python's walrus operator
Python's "walrus operator" is used for assignment expressions. Assignment expressions are a way of embedding an assignment statement inside another line of code.
pym.dev
October 18, 2026 at 6:02 PM
Python Tip #290 (of 365):

Pretty-print data structures with pp. 🧵

>>> from pprint import pp
>>> pp(user)
{'name': 'Trey',
'languages': ['Python', 'JavaScript'],
'address': {'city': 'San Diego', 'state': 'CA'}}

#Python #DailyPythonTip
October 17, 2026 at 6:02 PM