惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

G
Google Developers Blog
宝玉的分享
宝玉的分享
月光博客
月光博客
B
Blog
云风的 BLOG
云风的 BLOG
Google DeepMind News
Google DeepMind News
Engineering at Meta
Engineering at Meta
aimingoo的专栏
aimingoo的专栏
N
Netflix TechBlog - Medium
博客园_首页
GbyAI
GbyAI
人人都是产品经理
人人都是产品经理
A
About on SuperTechFans
Y
Y Combinator Blog
L
LangChain Blog
有赞技术团队
有赞技术团队
D
Docker
爱范儿
爱范儿
博客园 - 司徒正美
H
Hackread – Cybersecurity News, Data Breaches, AI and More
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
酷 壳 – CoolShell
酷 壳 – CoolShell
Microsoft Security Blog
Microsoft Security Blog
D
DataBreaches.Net

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
🐍 python args and kwargs explained simple — common mistak...
Python-T Poi · 2026-05-11 · via DEV Community

❓ Can You Really Use *args and **kwargs Beyond Simple Examples?

python args and kwargs explained simple

The *args and **kwargs syntax in Python is not just about passing extra arguments; it's about writing functions that adapt to evolving interfaces, wrap other functions cleanly, and avoid brittle parameter lists in real codebases. Most tutorials stop at toy examples, leaving developers unsure how to apply them in production-grade code.

📑 Table of Contents

  • ❓ Can You Really Use *args and **kwargs Beyond Simple Examples?
  • 🐍 args — Handling *Variable Positional Inputs
  • 🔧 Use Case: Flexible Logging Layers
  • ⚠️ Gotcha: Order Matters
  • 🧩 *kwargs — Working with *Arbitrary Keyword Arguments
  • 🔧 Use Case: API Client Builders
  • ⚠️ Gotcha: Don’t Blindly Forward Unknown Kwargs
  • 🤝 Combining *args and **kwargs for Full Flexibility
  • 🔍 How Parameter Resolution Works
  • ⚙️ Unpacking with * and ** in Function Calls
  • 🧠 When to Use args and kwargs in Real Projects
  • ✅ Do Use Them For
  • ❌ Avoid Overusing When
  • 📚 Example: Flexible Class Initialization
  • 🟩 Final Thoughts
  • ❓ Frequently Asked Questions
  • Can *args and **kwargs be used together in a function definition?
  • Is there a performance cost to using *args and **kwargs?
  • What happens if I pass a keyword argument that matches a named parameter and also include it in **kwargs?
  • 📚 References & Further Reading

🐍 args — Handling *Variable Positional Inputs

The *args syntax lets a function accept any number of positional arguments, collected into a tuple. When Python sees the * prefix on a parameter, it tells the function to pack all remaining positional arguments into a tuple accessible by the given name. This is implemented at the C-level in CPython using PyArg_ParseTupleAndKeywords and related APIs — the interpreter dynamically builds the tuple from the call stack.

def log_action(user, action, *details):
    print(f"User '{user}' performed '{action}'")
    if details:
        print(f"Details: {', '.join(str(d) for d in details)}")

# Usage
log_action("alice", "file_upload", "report.pdf", "size: 2MB", "encrypted=True")



User 'alice' performed 'file_upload'
Details: report.pdf, size: 2MB, encrypted=True

Enter fullscreen mode Exit fullscreen mode

🔧 Use Case: Flexible Logging Layers

Functions that wrap actions — like audit logging in admin systems — often don’t know what arguments the wrapped function will receive. *args allows the wrapper to pass through all positional inputs untouched.

def audit_log(func):
    def wrapper(*args, **kwargs):
        print(f"Calling {func.__name__} with args={args}, kwargs={kwargs}")
        return func(*args, **kwargs)
    return wrapper

@audit_log
def transfer_funds(from_id, to_id, amount, reason=None):
    print(f"Transferred ${amount} from {from_id} to {to_id}")

transfer_funds(101, 205, 500, reason="refund")



Calling transfer_funds with args=(101, 205, 500), kwargs={'reason': 'refund'}
Transferred $500 from 101 to 205

Enter fullscreen mode Exit fullscreen mode

⚠️ Gotcha: Order Matters

*args consumes all unmatched positional arguments, so it must come after any required positional parameters. You can't define a function like def bad_func(*args, x) — Python raises a SyntaxError.


🧩 *kwargs — Working with *Arbitrary Keyword Arguments

The **kwargs syntax collects any unmatched keyword arguments into a dictionary. Mechanistically, when Python processes a function call, keyword arguments not matched to formal parameters are packed into a dict object. This is efficient for configuration-heavy workflows because dictionary lookups are O(1), and the structure mirrors JSON-like data common in APIs and config files.

def create_user(name, email, **profile):
    user = {"name": name, "email": email}
    user.update(profile)  # Add optional fields
    print(f"Created user: {user}")
    return user

# Usage
create_user("Bob", "bob@example.com", role="admin", team="infra", active=True)



Created user: {'name': 'Bob', 'email': 'bob@example.com', 'role': 'admin', 'team': 'infra', 'active': True}

Enter fullscreen mode Exit fullscreen mode

🔧 Use Case: API Client Builders

When interfacing with REST APIs, query parameters or headers often vary by endpoint. Using **kwargs lets you write generic request wrappers.

import requests

def api_get(endpoint, **options):
    base_url = "https://api.example.com/v1"
    url = f"{base_url}/{endpoint}"

    # Extract specific keys, pass the rest as params
    headers = options.pop('headers', {})
    timeout = options.pop('timeout', 5)

    response = requests.get(url, params=options, headers=headers, timeout=timeout)
    return response.json() if response.ok else None

# Flexible calls
api_get("users", role="dev", active=True, timeout=10)
api_get("servers", region="us-west-2", headers={"Authorization": "Bearer xyz"})

Enter fullscreen mode Exit fullscreen mode

This pattern keeps your interface clean while allowing full control over HTTP parameters — all without bloating the function signature.

⚠️ Gotcha: Don’t Blindly Forward Unknown Kwargs

Passing every unknown keyword argument directly to another system can introduce security or stability risks. Always validate or sanitize **kwargs when interfacing with external systems. (Also read: 🐍 python multiple inheritance examples — common mistakes and how to fix them)

Use *args and **kwargs to defer decisions, not avoid design.


🤝 Combining *args and **kwargs for Full Flexibility

A function can accept both *args and **kwargs, making it capable of wrapping any callable with any signature. (Also read: 🐍 How to set up CI/CD for a Python Flask app using GitHub Actions — common mistakes and key tips)

This combination is foundational in decorators, middleware, and proxy functions — especially in frameworks like Django, FastAPI, or Flask, where handlers need to remain agnostic to underlying signatures.

def retry_on_failure(max_retries=3):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for attempt in range(1, max_retries + 1):
                try:
                    return func(*args, **kwargs)
                except Exception as e:
                    print(f"Attempt {attempt} failed: {e}")
                    if attempt == max_retries:
                        raise
            return None
        return wrapper
    return decorator

@retry_on_failure(max_retries=2)
def unstable_api_call(user_id):
    import random
    if random.random() < 0.7:
        raise ConnectionError("Network timeout")
    return {"status": "success", "data": f"profile_{user_id}"}

# Try calling
unstable_api_call(123)



Attempt 1 failed: Network timeout
Attempt 2 failed: Network timeout
...
# May eventually succeed or raise after 2 attempts

Enter fullscreen mode Exit fullscreen mode

🔍 How Parameter Resolution Works

Python resolves function arguments in this order: (Also read: 📦 Dockerfile best practices Python Flask — common mistakes and how to fix them)

  1. Positional arguments (matched to named parameters)
  2. Keyword arguments (by name)
  3. Default values for missing parameters
  4. *args collects unmatched positional arguments
  5. **kwargs collects unmatched keyword arguments

The interpreter uses a stack frame to bind names, and the * and ** operators control how excess values are packed or unpacked.

⚙️ Unpacking with * and ** in Function Calls

Just as *args packs positional arguments during definition, using * in a function call unpacks a sequence into positional arguments.

args = ["Alice", "edit_post", "post_id=456", "draft=True"]
log_action(*args)  # Equivalent to log_action("Alice", "edit_post", "post_id=456", "draft=True")

Enter fullscreen mode Exit fullscreen mode

Similarly, ** unpacks a dictionary into keyword arguments:

kwargs = {
    "name": "Charlie",
    "email": "charlie@example.com",
    "role": "analyst",
    "department": "data"
}
create_user(**kwargs)

Enter fullscreen mode Exit fullscreen mode

This bidirectional use — packing on definition, unpacking on call — is what makes the args and **kwargs syntax so powerful in dynamic codebases. *(More onPythonTPoint tutorials)


🧠 When to Use args and kwargs in Real Projects

Knowing how to use *args and **kwargs is not enough — you need judgment about when to apply them.

✅ Do Use Them For

  • Decorators — they must work with any function signature.
  • API wrappers — when forwarding arguments to another function or service.
  • Base classes or mixins — passing arguments up the MRO via super().init(*args, **kwargs).
  • Configuration layers — where optional settings are passed down.

❌ Avoid Overusing When

  • The function has a clear, stable interface — explicit is better.
  • You're hiding required parameters behind **kwargs — it hurts discoverability.
  • You're building public APIs — users prefer autocomplete-friendly signatures.

📚 Example: Flexible Class Initialization

In inheritance hierarchies, *args and **kwargs let child classes pass arguments up without knowing the parent’s full signature.

class Database:
    def __init__(self, host, port, **options):
        self.host = host
        self.port = port
        self.ssl = options.get("ssl", False)
        self.timeout = options.get("timeout", 30)

class MongoDatabase(Database):
    def __init__(self, db_name, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.db_name = db_name

# Usage
mongo = MongoDatabase(
    db_name="logs",
    host="10.0.1.100",
    port=27017,
    ssl=True,
    timeout=60
)
print(mongo.__dict__)



{'host': '10.0.1.100', 'port': 27017, 'ssl': True, 'timeout': 60, 'db_name': 'logs'}

Enter fullscreen mode Exit fullscreen mode

This pattern is common in ORM models, SDKs, and configuration systems — and it’s a real-world example of why the *args and **kwargs syntax matters beyond syntax.


🟩 Final Thoughts

*args and **kwargs are not just syntactic sugar — they’re tools for building adaptable, maintainable layers in Python applications. Used wisely, they reduce coupling between components, enable clean decorators, and simplify inheritance.

However, like any dynamic feature, they trade off some clarity for flexibility. The key is knowing when to lock down an interface with explicit parameters, and when to leave it open using *args and **kwargs. In mature codebases, you’ll often see them used deep in infrastructure code — middleware, wrappers, base classes — while public APIs remain explicit and documented.

Mastering the *args and **kwargs syntax means understanding both the mechanics and the design philosophy: defer decisions when you must, but document and constrain when you can.

❓ Frequently Asked Questions

Can *args and **kwargs be used together in a function definition?

Yes — a function can accept both *args and **kwargs, provided they appear in the correct order: regular arguments, then *args, then keyword-only arguments or **kwargs. The syntax def func(a, *args, x=1, **kwargs): is valid and commonly used in frameworks.

Is there a performance cost to using *args and **kwargs?

There is minimal overhead: *args creates a tuple, and **kwargs creates a dictionary. These are lightweight operations in CPython. The bigger concern is readability and debugging — stack traces and IDE hints may be less precise when arguments are hidden behind *args and **kwargs.

What happens if I pass a keyword argument that matches a named parameter and also include it in **kwargs?

Python raises a TypeError for ambiguous assignments. For example, if a function has a parameter name, you can't pass name both as a positional/keyword argument and inside **kwargs. The interpreter resolves names strictly and prevents duplication.

📚 References & Further Reading

  • Official Python documentation on calls and definitions — covers *args and **kwargs in depth: docs.python.org
  • Python data model reference for function call resolution: docs.python.org
  • Real-world decorator patterns using *args and **kwargs: docs.python.org