Level Up Your Python API Design: Mastering / and * Have you ever looked at a Python function signature and wondered what those / and * symbols actually do? While many developers stick to standard arguments, modern Python (3.8+) provides surgical precision over how functions receive data. Understanding this is key to building robust, self-documenting APIs. Check out this "Ultimate Signature" example: def foo(pos1, pos2, /, pos_or_kwd1, pos_or_kwd2='default', *args, kwd_only1, kwd_only2='default', **kwargs): print( f"pos1={pos1}", f"pos2={pos2}", f"kwd_only1={kwd_only1}", # ... and so on ) The Breakdown: Positional-Only (/): Everything to the left of the slash must be passed by position. You cannot call foo(pos1=1). This is perfect for performance and keeping your API flexible for future parameter renaming. Positional-or-Keyword: The "classic" Python parameters that can be passed either way. The Collector (*args): Grabs any extra positional arguments and packs them into a tuple. Keyword-Only: Everything after *args (or a standalone *) must be named explicitly. This prevents "magic number" bugs and makes the intent of the caller crystal clear. The Dictionary (**kwargs): Catches any remaining keyword arguments. Why should you care? Good code isn't just about making it work; it’s about making it hard to use incorrectly. By using these boundaries, you create a strict contract. You force clarity where it’s needed (Keyword-Only) and allow flexibility where it’s not (Positional-Only). Are you using these constraints in your daily development, or do you prefer keeping signatures simple? Let’s discuss below! 👇 #Python #SoftwareEngineering #CleanCode #Backend #ProgrammingTips #Python3 #CodingLife
Mastering Python API Design with / and * Symbols
More Relevant Posts
-
Technical post: I've been posting some graphs on here, talking about functions and "equivalence". This was all started by working on porting an MLOPs framework from python 3.10 to 3.12, and all the "dependency hell" one has to go through. Then naturally the question arose "What are the boundaries of one project to another, in terms of functions being called etc.,?" This led me down the rabbit hole (not too deep) of what happens when I do something like python -m <module> <somescript>. Specifically, what is a "no op" module, and what kind of ops can we inject, thanks to python being an interpreted language. A few years ago I'd worked on something along similar lines called TracePath, which provided a decorator to do something similar (e.g. who called who, how long it took, etc.). So I merged these two ideas (avoid decorating every function, have an "inspector" module) and ran this on a simple pandas dataframe creation. The resulting function invocation graph is the image attached to this post. When I ran it across the whole workflow (create, load, transform data etc.,), the graph had ~9000 connections. The nice thing is I can specify which modules (e.g. only pandas, or pandas and numpy) should be added to the graph etc. What do you think is the next logical thing to do with something like this? What kind of graphs would well structured software produce? How about badly written software? #graphs #swe #dependencyhell #python
To view or add a comment, sign in
-
-
🧠 Python Concept: strip(), lstrip(), rstrip() Clean your strings like a pro 😎 ❌ Problem text = " Hello Python " print(text) 👉 Output: " Hello Python " 😵💫 (extra spaces) ❌ Traditional Way text = " Hello Python " text = text.replace(" ", "") print(text) 👉 Removes ALL spaces ❌ (not correct) ✅ Pythonic Way text = " Hello Python " print(text.strip()) # both sides print(text.lstrip()) # left only print(text.rstrip()) # right only 🧒 Simple Explanation Think of it like cleaning dust 🧹 ➡️ strip() → clean both sides ➡️ lstrip() → clean left ➡️ rstrip() → clean right 💡 Why This Matters ✔ Clean user input ✔ Avoid bugs in comparisons ✔ Very useful in real-world apps ✔ Cleaner string handling ⚡ Bonus Example text = "---Python---" print(text.strip("-")) 👉 Output: "Python" 🐍 Clean data, clean code 🐍 Small functions, big impact #Python #PythonTips #CleanCode #LearnPython #Programming #DeveloperLife #100DaysOfCode
To view or add a comment, sign in
-
-
🚀 Python GIL vs No-GIL — Real FastAPI Benchmarks (Python 3.13) Free-threaded Python is no longer just an experiment — it’s starting to show real impact. I came across a benchmark comparing Python 3.12 (with GIL) vs Python 3.13t (No-GIL) using FastAPI, and the results are pretty interesting 👇 💡 Key Takeaways: 🔹 Massive CPU Boost (~8x) CPU-bound endpoints jumped from ~4 RPS to ~32 RPS — with ZERO code changes. This is what true parallelism across cores looks like. 🔹 Threading inside requests ≠ better performance Even without GIL, spawning threads inside a single request didn’t help. Why? Under load, request-level parallelism already saturates the CPU. Extra threads just add overhead. 🔹 I/O performance unchanged No surprise here — GIL was never the bottleneck for I/O-bound workloads. Async + I/O still behaves the same. 📊 What this means in practice: ✅ Use No-GIL Python when: - You have CPU-heavy APIs (ML inference, image processing, data pipelines) - High concurrency + CPU contention exists - You previously relied on multiprocessing to bypass GIL ❌ Don’t expect gains if: - Your app is mostly I/O (DB calls, HTTP requests) - You’re already using async effectively ⚠️ Things to keep in mind: - Free-threading is still evolving - Thread safety is now YOUR responsibility - Some C extensions may not be ready yet 🔥 The most exciting part? Same code. Same FastAPI app. Just a different Python runtime → 8x improvement. This could seriously change how we design backend systems in Python. Curious — would you switch to No-GIL Python for your APIs? #Python #FastAPI #BackendEngineering #Performance #Concurrency #AI #SoftwareEngineering
To view or add a comment, sign in
-
-
Today I learned about lambda functions in Python A lambda is just a small, anonymous one-liner function — no name, no `return`, just pure logic. Basic syntax: ``` lambda arguments: expression ``` Instead of writing: ```python def add(a, b): return a + b ``` You can write: ```python add = lambda a, b: a + b ``` But the real power shows up when you pair it with `map()`, `filter()`, and `sorted()`: ```python # Double every number list(map(lambda x: x * 2, [1, 2, 3, 4])) # → [2, 4, 6, 8] # Keep only even numbers list(filter(lambda x: x % 2 == 0, [1, 2, 3, 4, 5])) # → [2, 4] # Sort by second element sorted([(1,3),(2,1),(4,2)], key=lambda x: x[1]) # → [(2, 1), (4, 2), (1, 3)] ``` Key rule I'll remember: Use lambda when the logic is small and used once Avoid it when the logic gets complex — just write a proper `def` Small concept, but it shows up everywhere in Python backend code. #Python #Backend #LearningInPublic #100DaysOfCode #Django
To view or add a comment, sign in
-
Python Lists vs Tuples (Mutable vs Immutable) Lists = Mutable (can change) list_1 = ['apple', 'banana', 'orange', 'grape', 'mango'] list_2 = list_1 print(list_1) print(list_2) list_1[0] = 'Watermelon' print(list_1) print(list_2) Output: Both lists change (same reference in memory) --- Tuples = Immutable (cannot change) tuple_1 = ('apple', 'banana', 'orange', 'grape', 'mango') tuple_2 = tuple_1 print(tuple_1) print(tuple_2) # This will cause error tuple_1[0] = 'Watermelon' Error: TypeError: 'tuple' object does not support item assignment Key Insights: List → change allowed Tuple → change not allowed Both allow duplicates Both are ordered #Python
To view or add a comment, sign in
-
I just shipped a new feature to pydepgate: partial decode. When the scanner finds a high-entropy encoded blob, it now attempts to decode it and show you what's inside - without executing any of it. Here's what that looks like against the litellm 1.82.8 wheel. The 34,460-character string in proxy/proxy_server[.]py that I flagged in my last post? pydepgate now decodes it automatically. One layer of base64, 34,460 characters down to 25,844 bytes. Final form: Python source code. What's in that Python source? The first thing the decoder sees is import subprocess. Then import tempfile. Then import os. Then a PEM public key block. That's a complete second-stage payload, encoded and sitting inside a production Python package used by thousands of developers. The outer package does its advertised job. The encoded blob waits. pydepgate didn't execute it. It didn't import it. It decoded the bytes statically, identified the content type, extracted the indicators, and showed you the hex. The tool's job is to tell you what's there before anything runs - and now it can tell you more precisely what "there" is. --peek to enable decoding. --peek-chain to follow multi-layer encoding if the first decode produces another encoded blob. Still zero dependencies. Still stdlib only. pydepgate 0.2.0 is on PyPI now. By the way there's over 700 unittests, this project is covered extensively.
To view or add a comment, sign in
-
-
Python: sort() vs sorted() Have you ever had to pause for a second and think: “Do I need sort() or sorted() here?” 😅 This is the common Python confusions. Let’s clear it up. 🔹 list.sort() ◾ A method (belongs to list objects) ◾ Works only on lists ◾ Sorts the list in-place ◾ Changes the original list ◾ Returns None Example: numbers = [3, 1, 4, 2] numbers.sort() print(numbers) # [1, 2, 3, 4] 🔹 sorted() ◾ A function (built-in Python function) ◾ Returns a new sorted list ◾ Does NOT change the original ◾ Works on any iterable Example: numbers = [3, 1, 4, 2] new_numbers = sorted(numbers) print(new_numbers) # [1, 2, 3, 4] print(numbers) # [3, 1, 4, 2] The key difference: sort() → changes your original data sorted() → keeps your original data safe 💡 Quick way to remember: 👉 If you want to keep the original, use sorted() 👉 If you want to modify the list directly, use sort() #Python #Programming #LearnPython #DataScience #LearningJourney #WomenInTech
To view or add a comment, sign in
-
-
I think dictionaries might be the first Python topic that actually feels like organizing real life. 🐍 Day 08 of my #30DaysOfPython journey was all about dictionaries, and this one felt especially useful because it is basically how Python stores meaningful information. A dictionary is an unordered, mutable key-value data type. You use a key to reach a value — simple, but powerful. Today I explored: 1. Creating dictionaries with dict() built-in function and {} 2. Storing different kinds of values like strings, numbers, lists, tuples, sets, and even another dictionary 3. Checking length with len() 4. Accessing values using key name in [] or get() method 5. Adding and modifying key-value pairs 6. Checking whether a key exists using in operator 7. Removing items with pop(key), popitem() (removes the last item), and del 8. Converting dictionary items with items() which returns a dict_item object that contains key-value pairs as tuples 9. Clearing a dictionary with clear() 10. Copying with copy() and avoids mutation 11. Getting all keys with keys() and values with values(). These will return views - dict_keys() and dict_values() What stood out to me today was how dictionaries make data feel searchable instead of just stored. That key-value structure makes them one of the most practical tools in Python when working with real information. One more day, one more topic, one more step toward thinking in Python instead of just reading Python. When did dictionaries finally stop feeling confusing for you — or are they still one of those topics that need a second look? Github Link - https://lnkd.in/ewzDyNyw #Python #LearnPython #CodingJourney #30DaysOfPython #Programming #DeveloperJourney
To view or add a comment, sign in
-
😊❤️ Todays topic: Topic: Polymorphism in Python: ============= Polymorphism means “one interface, multiple implementations”. In simple terms, the same method name can behave differently depending on the object. Example 1: Same method, different classes class Dog: def sound(self): print("Bark") class Cat: def sound(self): print("Meow") for animal in [Dog(), Cat()]: animal.sound() Output: Bark Meow Explanation: Both classes have the same method name, but different behavior. Example 2: Built-in polymorphism print(len("Hello")) # string print(len([1, 2, 3])) # list Output: 5 3 Explanation: len() works differently for different data types. Example 3: Method overriding class Parent: def show(self): print("Parent") class Child(Parent): def show(self): print("Child") obj = Child() obj.show() Output: Child Key Points: Same method name, different behavior Achieved using method overriding or different classes Improves flexibility and code reuse Interview Insight: Polymorphism allows writing generic and reusable code that works with different object types. Quick Question: Is method overloading supported in Python like Java? #Python #Programming #Coding #InterviewPreparation #Developers
To view or add a comment, sign in
-
Python 3.14 just dropped something I didn't know I needed. t-strings. For years I've been using f-strings for everything. They're clean, they're fast, and I love them. But there's always been that one nagging problem — you can't intercept what goes inside them. The moment you write f"Hello {user_input}", that string is already built. No hooks. No validation. No custom logic. Just a finished string. t-strings change that completely. Instead of immediately resolving to a string, t"Hello {user_input}" gives you back a Template object. You get both the static parts and the interpolated values — separately — before anything is joined together. That means you can sanitize SQL inputs, escape HTML, validate API payloads, or run any custom logic on the values before they ever become a string. The syntax feels identical to f-strings. The power underneath is completely different. I've already started thinking about how this simplifies things in backend work — especially anywhere user input touches a query or a template. The safety implications alone are massive. This is one of those features that looks small in the changelog and then quietly becomes the way you write Python. Have you tried t-strings yet? What's your first use case? #Python #Python3.14 #BackendDevelopment #SoftwareEngineering #WebDevelopment
To view or add a comment, sign in
More from this author
Explore related topics
Explore content categories
- Career
- Productivity
- Finance
- Soft Skills & Emotional Intelligence
- Project Management
- Education
- Technology
- Leadership
- Ecommerce
- User Experience
- Recruitment & HR
- Customer Experience
- Real Estate
- Marketing
- Sales
- Retail & Merchandising
- Science
- Supply Chain Management
- Future Of Work
- Consulting
- Writing
- Economics
- Artificial Intelligence
- Employee Experience
- Workplace Trends
- Fundraising
- Networking
- Corporate Social Responsibility
- Negotiation
- Communication
- Engineering
- Hospitality & Tourism
- Business Strategy
- Change Management
- Organizational Culture
- Design
- Innovation
- Event Planning
- Training & Development
This is a great example of how function signatures can enforce better API design. Keyword-only arguments in particular feel underrated — they make intent much clearer and reduce misuse. Curious — do you find this approach practical in larger codebases, or does it add too much complexity over time?