Trey Hunner 🐍
#Python & #Django educator & team trainer
I help folks sharpen their Python skills with https://PythonMorsels.com🐍🍪
Also: ostrovegan, sentientist, YIMBY, and I think economics is highly underrated. I don't post about any of those topics very often.
he/him
I made a thing last week and Earth Day seems like a great day to announce it. 🌏
https://Whereabouts.Earth is a fun (for me at least) app for learning the location of every country on Earth.
It uses a very effective learning technique (spaced repetition), but you don't need to know how that part works. It will work.
My geography knowledge has improved a LOT over the past week.
Join me in learning about the only home we'll ever have.
(And please share your feedback if you actually use this)
T-strings are primarily useful for the maintainers of libraries that are used by other Python developers.
Read more 👉 https://trey.io/n4mlgb
Python Tip #99 (of 365):
Don't convert pathlib.Path objects to strings
Using a pathlib.Path object in an f-string or a print call is fine and I do this often.
But if you THINK you need to convert a pathlib.Path object to a string to pass it off to some other path-handling utility, you probably don't need to. Most path-handling utilities in Python support pathlib.Path objects just fine.
Python Tip #106 (of 365):
Name ambiguous unicode characters with "\N{...}"
When you need to represent a non-ASCII character, you can either:
1. Copy-paste the character directly into your file
2. Use a "\u" or "\U" prefix to represent the character by its code point
3. Use "\N" to represent the character by its name
🧵 (1/3)
Python Tip #97 (of 365):
When you need to read/write a whole file all at once, use the appropriate pathlib.Path helper method
Instead of:
with open(path) as file:
contents = file.read()
Do this:
contents = path.read_text()
And instead of:
with open(path, mode="wt") as file:
file.write(contents)
Do this:
path.write_text(contents)
This is a magical moment for me... the Cabo card game has been mentioned in a PyCon promo post!
I've been teaching people Cabo since my first PyCon US and I've met SO many people from spreading this card game during PyCon.
I very much look forward to teaching Cabo (and watching others teach it I hope) at #PyConUS this year.
$ docker volume prune
...
Total reclaimed space: 224.4GB
Yikes...
Python Tip #118 (of 365):
Instead of argparse.FileType, use pathlib.Path
The argparse module's FileType is deprecated (as of Python 3.14).
It has known issues: no newline argument accepted, encourages not using a context manager, etc.
Instead of argparse.FileType you should use pathlib.Path.
Using "type=Path" will auto-convert given arguments to pathlib.Path objects.
That way all command-line-provided file paths will turn into pathlib.Path objects automatically!
Stay at The Westin and play Cabo and other card games and board games in the lobby in the evenings!
All are welcome to join. You'll be able to spot us because we'll look like PyCon attendees. Come over, say hi, play games, and chat.
Big news (for me at least): pprint on Python 3.15 is going to allow MUCH friendlier output! 🎉
Instead of:
pprint.pprint(some_object)
If you do this:
pprint.pprint(some_object, indent=4, expand=True)
You'll see output that looks like the most commonly used modern Python line-wrapping style in actual code!
I rarely use pprint because its output style is so bizarre.
I may start using it on Python 3.15 (even though the version I'll want to use will take 23 extra characters to type).
Python Tip #100 (of 365):
Prefer the pathlib.Path object's is_file() and is_dir() methods over exists()
The exists method tells you SOMETHING is there but not WHAT.
Using is_file() or is_dir() is more explicit about what you're actually checking for, and usually what you actually want.
Usually when I find myself using exists(), I'll realize that I wanted one of the more specific methods instead.
Have a date string and want to find the format string needed to parse it?
Read more 👉 https://trey.io/l4b84k
Python Tip #105 (of 365):
When breaking a function call or list literal over multiple lines, use trailing commas.
For example, take this list:
fruits = [
"lemons",
"apples",
"watermelon",
]
Moving "lemons" to the end is easy when there's a trailing comma: just cut and paste.
Without trailing commas, moving "lemons" to the end means adding a comma after "watermelon" AND removing one after lemons.
🧵 (1/2)
I've updated my blog post on how to have a great first #PyConUS: https://trey.io/first-pycon
The only TBD links are the volunteering link and the open spaces links.
I'm considering making an audio recording of this post for folks to listen to during the travels to Long Beach. Anyone interested in that?
Python Tip #98 (of 365):
Don't use open method on pathlib.Path objects 🧵
Instead of this:
with path.open() as file:
...
Prefer this:
with open(path) as file:
...
Since Python 3.6, pathlib.Path objects can be passed to the built-in open function.
pathlib.Path's open method is a relic from an earlier version of pathlib that wasn't yet fully embraced by Python's various path-handling features.
I recommend using Python's built-in open() function everywhere.
Python Tip #104 (of 365):
Use an _ to represent a placeholder variable.
This can be handy when you need to use range to loop N times but you don't care about the current iteration number in the loop:
matrix = [[0] * 3 for _ in range(3)]
Or when you're unpacking a tuple and one or more tuple values are unimportant:
[(item, _)] = collections.Counter(items).most_common(1)
When I see _ I think "I don't need to care about that value".
@pythonbytes@fosstodon.org some interesting things you may want to consider in an upcoming episode:
1. Savannah Ostrowski's new Core Dispatch newsletter: https://coredispatch.xyz
2. my article on pdbrc files: https://treyhunner.com/2026/04/customizing-pdb-with-pdbrc/ or Ned's *much* earlier article that I discovered after I published mine: https://nedbatchelder.com/blog/200704/my_pdbrc
3. I can't remember whether you've covered this and it might not be time yet (it's only a draft PEP still) but I found the PEP on d-strings interesting: https://peps.python.org/pep-0822/
Python Tip #108 (of 365):
Don't use semicolons.
Want to put 2 statements on one line?
from rich.traceback import install; install(show_locals=True)
Don't.
Just use 2 lines:
from rich.traceback import install
install(show_locals=True)
It's more readable.
That's the entirety of today's tip. 🤷
Python Tip #107 (of 365):
Use the walrus operator to simplify "while" loops.
This generator function reads a file in chunks:
def read_in_chunks(path):
with open(path, mode="rb") as file:
chunk = file.read(8192)
while chunk:
yield chunk
chunk = file.read(8192)
Notice that "chunk = file.read(8192)" appears twice: once before the loop and once at the end.
This is a somewhat common pattern with "while" loops.
🧵 (1/2)
“Parentheses are used for 3 things in Python: calling callables, creating empty tuples, and grouping.”
Read more 👉 https://pym.dev/unnecessary-parentheses/
“Every iterable-accepting class is a comprehension-like tool waiting to happen.”
Read more 👉 https://pym.dev/custom-comprehensions/
“Python typically prints unhandled exceptions and warning messages to standard error.”
Read more 👉 https://pym.dev/standard-error/
“But del is a statement, not a function.”
Read more 👉 https://pym.dev/unnecessary-parentheses/
“While splitting on a line feed character will often work, I recommend using the string splitlines method instead.”
Read more 👉 https://pym.dev/splitlines/
