Skip to content
DevMeme
3920 of 7435
Python's Keyword Arguments Have Always Been a Feature
Languages Post #4267, on Mar 8, 2022 in TG

Python's Keyword Arguments Have Always Been a Feature

Why is this Languages meme funny?

Level 1: Always has been

Imagine you’re playing with a shape-sorting toy that has different holes for different shapes – a circle hole, a square hole, and a triangle hole. You have matching pieces for each hole. At first, you always put the circle piece in first, then the square, then the triangle, because you thought that was the rule. But one day you realize you can put the triangle piece in first, or the square first, or any order you want! It doesn’t matter – each piece will always fit in its matching hole no matter when you do it. This surprises you: “Has this always been okay?” And your older friend says, “Always has been.” In other words, the toy was always designed so you could drop the pieces in any sequence. You just didn’t know until now.

That’s exactly what’s happening with Python in the meme. Python functions are like that shape sorter: each argument has a name (like each shape has its matching hole), so you can give them to the function in whatever order, and they’ll still land in the right spot. It’s a funny “Aha!” moment – finding out something has been true all along and feeling both amazed and a tiny bit silly for not noticing it earlier.

Level 2: Mix-and-Match Arguments

Let’s break down what’s happening in this meme. We’re dealing with a fundamental Python concept: positional vs. keyword arguments in function calls. In Python, a function can be called by matching arguments either by position (the order they appear) or by keyword (explicitly naming each parameter). The meme’s code example defines a simple function:

def f(a, b, c):
    print(a, b, c)

This function f takes three parameters a, b, and c and simply prints them out. Normally, if you call f with positional arguments, you’d supply them in order, like f(2, 1, 3). That would assign a = 2, b = 1, c = 3 by their positions (first value to a, second to b, third to c). Most programming languages work this way by default – the position in the call determines which parameter gets which value.

Keyword arguments are different. When calling f, you can explicitly name each parameter and give it a value, using the syntax param_name=value. The magical part is that if you call the function this way, you don’t have to follow the original order of parameters at all! Python will match the names you provided with the function’s parameters behind the scenes. In the snippet shown, the call is:

f(c = 3, a = 2, b = 1)

Here, we provided the values in a completely mixed order: we gave c first, then a, then b. Despite the unusual ordering, Python knows exactly what you mean. It sees c = 3 and places 3 into the slot for c, sees a = 2 and puts 2 into a, then b = 1 into b. The function f doesn’t care about the order of these keyword arguments; all it cares is that each of its parameters gets some value. The output 2 1 3 confirms this – it printed a then b then c, showing a got 2, b got 1, and c got 3, matching the names we used. No errors, no swap in values, just a normal successful call.

For someone new to Python (or coming from a language without this feature), this can be surprising. They might ask, “Wait, you can do that? Since when?!” The answer, as the meme humorously points out, is: since always. Python has allowed parameter_order_flexibility from the very beginning. It’s not a trick or a recent addition – it’s a core part of how function calls work in Python. In fact, this flexibility is one reason people find Python code very readable. You can name arguments at the call site to make your intent clear. For example, if a function is defined as send_email(to, subject, cc, bcc), you could call it like send_email(subject="Hello", to="[email protected]", bcc=None, cc=None). Even if you mixed up the order, each value ends up in the right place because of the names.

The meme uses the popular “Always has been” format with two astronauts to dramatize this discovery. In that format, one character uncovers a surprising fact (in this case, the developer realizes Python’s function arguments don’t need to follow a fixed order if named), and another character reveals that it’s not new at all (it’s been true the whole time). The first astronaut, looking at Earth (which represents the truth about Python’s keyword arguments), says “How long has Python been like this?” in disbelief. The second astronaut, pointing a gun (for comedic effect, as if this truth is about to blow the person’s mind), replies “Always has been.” It’s a cheeky way to say “yep, this is an old truth, you just didn’t know.”

To a junior developer or someone still learning Python, the takeaway is: Python’s syntax lets you mix and match arguments by name. If you ever forget the order of parameters or want to make your code clearer, you can call functions using name=value pairs. Just remember that if you use one keyword argument in a call, any further arguments should also be keywords (you can’t put a positional argument after a keyword argument in the same call). But you can certainly reorder them as you like when they’re all keywords. This feature can save you from mistakes and make the code easier to read. It’s one of those little Python perks that feels very natural once you know it’s there. The meme is funny because it captures that exact moment of learning – the “Oh wow!” realization that Python had this capability all along and you’re only discovering it now.

Level 3: Parameter Permutations Permitted

Python’s function calls have a superpower that often catches newcomers off guard: you can pass arguments by name in any order, and it just works. In the meme, an astonished astronaut represents a developer who’s just discovered this LanguageFeature. They ask in disbelief, “How long does Python act like this?” Meanwhile, the second astronaut (a seasoned Pythonista with a proverbial gun of truth) delivers the punchline: “Always has been.” 🤯

This scene is a humorous take on a real LanguageQuirk. In Python, keyword arguments let you bind function parameters by name rather than position. That means the order of those arguments doesn’t matter at all – as long as each parameter name is specified, Python will match things up correctly. The code snippet in the meme’s top-left illustrates it clearly:

>>> def f(a, b, c):
...     print(a, b, c)
...
>>> f(c = 3, a = 2, b = 1)
2 1 3

Here, even though the function f is defined with parameters (a, b, c) in that order, the call f(c=3, a=2, b=1) still prints 2 1 3. Python assigned a = 2, b = 1, c = 3 by matching names, ignoring the fact that we supplied them in a jumbled sequence. Many strictly positional languages (like C or Java) don’t allow this kind of flexibility – you’d have to pass values in the exact order the function expects. A developer coming from such a background might assume Python works the same way and never realize they can shuffle arguments around. When they do realize it, it can feel like a galactic revelation: a feature hiding in plain sight all along!

The humor works on multiple levels of DeveloperHumor. First, there’s the classic “Always has been” astronaut meme format – often used to highlight an obvious truth that someone just discovered far too late. It’s a comically exaggerated way to say “Yep, that’s how it’s always been, surprise!” Second, the specific SyntaxHumor here is that Python’s syntax for function calls is more powerful than one might assume. Experienced Python devs chuckle because they’ve either seen this realization dawn on others or remember their own “wait, you mean I could’ve been doing this the whole time?!” moment. It’s both a point of pride (cool, Python is intuitive and flexible!) and a lighthearted jab – how did you miss something so fundamental? The imaginary gun-toting senior dev in the meme playfully “confronts” the junior for being late to the party.

From an architecture perspective, Python’s function calling convention was designed with keyword arguments from the start (indeed, this feature has been in Python since the 1990s). Under the hood, when you call f(c=3, a=2, b=1), the interpreter builds a dictionary of the keywords: {'c': 3, 'a': 2, 'b': 1}. The function then receives those named values, and it doesn’t matter in what order that dictionary was populated. Order isn’t just ignored – it’s literally irrelevant to the mapping process. This is why the second astronaut’s reply is technically accurate: Python always allowed arbitrary order for keyword arguments. It wasn’t a new patch or update; it’s a deliberate design choice emphasizing clarity and flexibility. In fact, this feature is a lifesaver when functions have many optional parameters – you can specify only the ones you care about by name and skip the rest. Seasoned devs know this well and use it to write more readable code (for example, calling open(file="data.txt", mode="r") instead of open("data.txt", "r") makes it obvious which argument is which).

The meme playfully condenses all that context into one astronaut_gun_template scene. It captures the mix of surprise and inevitability: surprise for the dev who just connected the dots, and inevitability because, well, Python has been behaving like this all along. Fellow programmers find it funny because we’ve either been that wide-eyed astronaut or we’ve had to explain such “obvious” things to others. It’s a shared nod to those “Aha!” moments in coding – a reminder that even features clearly documented in a language can feel like hidden secrets if you never stumbled across them. In the end, the meme is poking fun at that sudden realization, with Python proudly standing there like the Earth in the background, silently saying “I’ve been this way the whole time, you just finally noticed.”

Description

This image uses the popular 'Always has been' meme format, which depicts two astronauts in space against a starry background. One astronaut, looking at a snippet of Python code, asks, 'How long does Python act like this?'. The second astronaut, standing behind the first and pointing a pistol at their back, replies, 'Always has been'. The code snippet in the top-left corner shows a Python function being defined as 'def f(a, b, c): print(a, b, c)'. The function is then called with keyword arguments in a different order: 'f(c = 3, a = 2, b = 1)', which correctly produces the output '2 1 3'. The humor comes from a developer's apparent surprise at discovering named (or keyword) arguments, a fundamental and long-standing feature of the Python language. The meme playfully suggests this feature is as old and established as the universe itself, mocking the idea that it might be a new or strange behavior

Comments

37
Anonymous ★ Top Pick Discovering keyword arguments in Python is the programmer's equivalent of realizing the screwdriver has a Phillips head on the other end. It's not a new feature; you've just been using it wrong the whole time
  1. Anonymous ★ Top Pick

    Discovering keyword arguments in Python is the programmer's equivalent of realizing the screwdriver has a Phillips head on the other end. It's not a new feature; you've just been using it wrong the whole time

  2. Anonymous

    “Wait - Python lets me permute kwargs and it just works?” Old-timer Python devs: “Always has been.” Me, eyeing our decade-old Java module with 14 telescoping constructors: “So that Builder pattern was just us LARPing as a compiler?”

  3. Anonymous

    After 15 years of Python, you realize the real backward compatibility nightmare isn't Python 2 vs 3 - it's explaining to junior devs why your legacy codebase has defensive **kwargs everywhere because someone in 2008 thought positional-only parameters were 'unpythonic'

  4. Anonymous

    Keyword args have bound by name since before your codebase existed - the only positional thing here is the gun

  5. Anonymous

    Python's keyword arguments have been flexing their positional independence since before most frameworks were born - proving that sometimes the real legacy code is the language feature that's been there all along, quietly enabling every config function with 47 optional parameters you've ever written

  6. Anonymous

    Keyword args: decoupling param order from sig rigidity, until that sneaky positional slips in and nukes your spaceship

  7. Anonymous

    We’ve spent quarters bikeshedding parameter order in API reviews; Python shipped kwargs ages ago - our RPC generator just never got the memo

  8. Anonymous

    Python kwargs: order is a suggestion; names are the ABI. Rename “timeout” to “deadline” and your “minor” release becomes an incident - always has been

  9. @NexonSU 4y

    i don't get it...

  10. @maggelia 4y

    Neither do I

  11. @farkasma 4y

    I admittedly don't know or use python, but this IS what I would expect it to do

  12. @Odbjorn 4y

    It's called named arguments in python

    1. @dugeru42 4y

      no

    2. @dugeru42 4y

      https://stackoverflow.com/a/9450673

  13. @s2504s 4y

    Do other languages not have that ability? IDK I am teapot

    1. @sylfn 4y

      C++: no ability to do this except some shitty workarounds like struct kek { int a, b, c; }; void fun(kek a) { cout << a << " " << b << " " << c; } fun(kek{.c = 3, .a = 2, .b = 1}); (syntax may be incorrect bc i dont use this feature)

      1. @feskow 4y

        almost

        1. @sylfn 4y

          declaration order? try clang OR g++ witg std=gnu OR visual studio

        2. @callofvoid0 4y

          What does . do before struct parametr names

    2. @QutePoet 4y

      In JavaScript it's possible.

    3. @sotnii13 4y

      Also in dart you can do this

  14. @s2504s 4y

    Lol, but true 😂

  15. Vitalik 4y

    A lot of languages can do that, I'm using it a lot in C#, so I didn't get this meme

  16. . 4y

    >>> f(c := 3, a := 2, b := 1) 3 2 1

  17. @CcxCZ 4y

    It's even better in OCaml where you can: let foo = 1; let bar = 2; func(.foo, .bar) As a shorthand to func(foo=foo, bar=bar)

    1. @CcxCZ 4y

      This is handy when you are passing same named argument through several functions for example.

  18. P S 4y

    This is what HTCPCP-TEA exists for... Its a real rfc.

  19. Deleted Account 4y

    Don't you feel bad while posting something like this?

    1. @sylfn 4y

      why should he?

      1. @beton_kruglosu_totchno 4y

        because cringe shortens life expectancy

    2. @CcxCZ 4y

      https://m.xkcd.com/1053/ Be kind.

  20. @ZgGPuo8dZef58K6hxxGVj3Z2 4y

    Lmao

  21. @callofvoid0 4y

    i still don't get where this error is used

    1. @sylfn 4y

      April 1st

      1. @callofvoid0 4y

        ah

    2. @RiedleroD 4y

      afaik it's meant for when you make a request for a server which it doesn't handle because it's not the right kind of server - e.g. when you make a https request to a http server. Though the code was introduced on April Fool's, so it was named humorously and nobody uses it for anything. Maybe there's a good replacement, idk. But a 404 or 403 usually suffices for those situations.

      1. @callofvoid0 4y

        thanks a lot!

Use J and K for navigation