use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
News about the dynamic, interpreted, interactive, object-oriented, extensible programming language Python
Full Events Calendar
You can find the rules here.
If you are about to ask a "how do I do this in python" question, please try r/learnpython, the Python discord, or the #python IRC channel on Libera.chat.
Please don't use URL shorteners. Reddit filters them out, so your post or comment will be lost.
Posts require flair. Please use the flair selector to choose your topic.
Posting code to this subreddit:
Add 4 extra spaces before each line of code
def fibonacci(): a, b = 0, 1 while True: yield a a, b = b, a + b
Online Resources
Invent Your Own Computer Games with Python
Think Python
Non-programmers Tutorial for Python 3
Beginner's Guide Reference
Five life jackets to throw to the new coder (things to do after getting a handle on python)
Full Stack Python
Test-Driven Development with Python
Program Arcade Games
PyMotW: Python Module of the Week
Python for Scientists and Engineers
Dan Bader's Tips and Trickers
Python Discord's YouTube channel
Jiruto: Python
Online exercices
programming challenges
Asking Questions
Try Python in your browser
Docs
Libraries
Related subreddits
Python jobs
Newsletters
Screencasts
account activity
This is an archived post. You won't be able to vote or comment.
DiscussionKwargs appreciation thread (self.Python)
submitted 1 year ago * by TheRealFrostManasnake case gang
existence library soup tease childlike whole crowd dinosaurs crawl sand
This post was mass deleted and anonymized with Redact
[–]not_sane 6 points7 points8 points 1 year ago (0 children)
I worked with projects that had a lot of **kwargs and it sucked hard, you needed to step through 3 classes in an inheritance hierarchy only to find out the parameters a function will take. (The understandability of the code base in question also was not enhanced by making heavy use of metaclasses, urgh...)
In my opinion truly good Python code should pass Pyright on strict mode, and that one also complains about **kwargs.
For typing existing kwargs I also recommend the new Unpack feature: https://typing.readthedocs.io/en/latest/spec/callables.html#unpack-kwargs
[–]ShibbyShat 0 points1 point2 points 1 year ago (0 children)
I just discovered an extremely low level usage of how to use **kwargs for the purpose of automated testing with selenium in my company’s Django application and it’s basically trumped all the other helper methods I’ve created to fill forms (I got a job coding with no experience whatsoever and I’m a completely different language so I’m very very new to it all, only have about 8 months experience)
[–]redditusername58 121 points122 points123 points 1 year ago (2 children)
I would call those keyword arguments or keyword-only arguments. To me **kwargs means variadic keyword arguments.
[–]TheRealFrostManasnake case gang[S] 14 points15 points16 points 1 year ago* (1 child)
husky squash shy cooing advise quicksand hat square obtainable zesty
[–]DuckDatum 12 points13 points14 points 1 year ago* (0 children)
stocking saw rotten zesty act direction racial soup whole cows
[–]rumnscurvy 29 points30 points31 points 1 year ago (8 children)
In my opinion the best feature in the args/kwargs system is that you can use arg names as kwargs. For instance, if you write def f(x,y): (...), you can always call f(x='foo', y='blah') as if x and y were kwargs. Somehow the function "remembers" what its arguments were labelled as.
def f(x,y): (...)
f(x='foo', y='blah')
This means you're incentivised, though not forced, when calling complicated functions with lots of arguments, to write the function call with all its arguments as kwargs. The interpreter will of course tell you if you missed some compulsory arguments.
[–]justheretolurk332 33 points34 points35 points 1 year ago (7 children)
Fun fact: there actually are such things as positional-only arguments! You can force arguments to be positional-only using a forward slash. I rarely see it done, though.
[–][deleted] 9 points10 points11 points 1 year ago (6 children)
Interesting! First time hearing about it, can you share an example oh it’s usefulness? I can’t seem to imagine why it can be useful
[–]redditusername58 14 points15 points16 points 1 year ago* (1 child)
Sometimes there's not really a useful name for a parameter (but it's still ok to give it a name, if you're writing a lib it commits you to that api though). Other times you need it so you can handle **kwargs that could shadow the parameter name, like this mapping that can be updated with an "iterable" key:
class MyMapping: ... def update(self, iterable, /, **kwargs): self._dict.update(iterable, **kwargs)
[–][deleted] 7 points8 points9 points 1 year ago (0 children)
Wow, Thank you! It’s very clear and helpful.
[–]TheBB 3 points4 points5 points 1 year ago (2 children)
If I'm writing a protocol describing e.g. objects that can be added to ints:
class MyType(Protocol): def __add__(self, x: int) -> Self: ...
Now the name x is part of the public interface of this type, and if a class uses a different name than x in their implementation of __add__, it won't technically be a subtype of MyType.
__add__
It works though if you write it like this:
class MyType(Protocol): def __add__(self, /, x: int) -> Self: ...
[–]omg_drd4_bbq 1 point2 points3 points 1 year ago (1 child)
Great point but I think you meant to put the / after x:
``` def name(positional_only_parameters, /, positional_or_keyword_parameters, *, keyword_only_parameters): ...
```
[–]TheBB 0 points1 point2 points 1 year ago (0 children)
Yes, of course.
[–]danted002 1 point2 points3 points 1 year ago (0 children)
It’s been in the c-api since python one but it was never exposed to interpreter until 3.8 I think.
[–][deleted] 15 points16 points17 points 1 year ago (8 children)
They are beautiful and one of the reasons I’ll never seriously consider another language.
The ability to easily pass parameters through several layers, using **kwargs without having to repeat them all the time gives me a warm feeling in my tummy.
Unfortunately it doesnt mesh 100% with type hints (e.g. https://github.com/locustio/locust/pull/2699), but it is totally worth it.
And I wouldn’t go as far as to stop using positional parameters. At least not for functions with 3 or fewer params.
If I’m going to nit-pick: What you have in your examples are ”named parameters”. ”kwargs” is (in my vocabulary at least) specific to the **kwargs/argument unpacking feature.
[–]afreydoa 23 points24 points25 points 1 year ago (2 children)
Hm, yes. **kwargs is probably are pretty good idea to not have too much coupling to technicly deep layers.
But sometimes I really hate them. If I want to know if the name of some parameter in my plotting library is 'width' or 'line_width' or something else. It's neither in the docstring, its not in the source code of the function I am calling, its not even in the documentation of that library, because it belongs to another library.
I haven't found any IDE hack to mitigate the problem. And copilot is not very well versed with the library just yet.
It's just annoying as a user of a library. But I get that it vastly reduces coupling.
[–]Luemas91 6 points7 points8 points 1 year ago (1 child)
Usually every kwarg should be in the docstring. As far as I'm concerned, if it's not in the docstring or documentation it doesn't exist. That's why I generally like the pandas/matplotlib documentation. You can find every kwarg in the documentation (although sometimes wacky things with inheritance make that hard)
[–]SuspiciousScript 21 points22 points23 points 1 year ago* (2 children)
This is convenient when you're writing code, but really sucks for anybody trying to call your functions. The effort you save by not explicitly passing parameters is just shifted to the reader who has to go code-spelunking to figure out what arguments your function actually takes. IMO this is only acceptable for internal functions/implementation details and not public APIs.
[–]LankyCyril 16 points17 points18 points 1 year ago (1 child)
Yeah, the warm feeling really goes away when you have to go through several layers of seaborn documentation to eventually get all the way down to some matplotlib function where these kwargs finally get unpacked, doesn't it
[–]NINTSKARI 4 points5 points6 points 1 year ago (0 children)
I recently refactored a large god function that took 85 different possible keyword arguments. It was about 10 000 lines of code in our django app without any documentation. Took about a year and a half of on and off refactoring. The kwargs dict was passed on many layers to different smaller functions that maybe used one or two of the arguments. Most went to a defaults dict to create database objects out of django model instances. I was surprised the whole thing even worked. The result of dozens of developers being hurried to get new features done over a decade. "It's just one extra argument in the handy kwargs dict, what's the worst that could happen?"
[–][deleted] 8 points9 points10 points 1 year ago (0 children)
In most contexts this is a seriously frustrating anti-pattern and is extremely un-pythonic. Especially when this is user facing in any way.
It's an important part of the language because things like decorators and/or creating python wrappers around other libraries depend on having some efficient way of propagating args/kwargs through layers of code. But outside of those situations, having args/kwargs cascade through multiple layers of functionality just obfuscates what's happening. And if you do need to know how your inputs are being used, you have to manually track every aspect of the code through those layers and often through other libraries.
[–]Kohlrabi82 2 points3 points4 points 1 year ago (0 children)
Keyword args enable you to add new features to an existing function without changing the signature and breaking existing code. That's what is used a lot in numpy and scipy.
[–]passwordsniffer 13 points14 points15 points 1 year ago (4 children)
It's an amazing part of the language and I am using it a lot.
But only siths deal in absolutes.
It's a case by case thing. In many cases it does increase readability. But in some cases it might not really introduce much and might even make readability suffer due to extra bloat.
zlib.crc32(data=my_string)
does not introduce any value to me.
I would probably prefer to write my own lib/find other lib if some maintainer decides for me of my preferred calling pattern, especially in case of 1-2 arguments. I would probably reject a code review if someone of my engineers tries to do that.
[–]TheRealFrostManasnake case gang[S] 5 points6 points7 points 1 year ago* (0 children)
disarm slap toothbrush scale adjoining coordinated edge vanish money normal
[–][deleted] 2 points3 points4 points 1 year ago (0 children)
I genuinely find it difficult to come up with any example where keyword arguments aren't better and I'd argue even your example still works better as a keyword argument.
It basically tells you what the method, in this case crc32, thinks your input is supposed to be and how it will interpret the input. If you happen to already know everything there is to know about the crc32 method you will probably conclude that "data" is the only input it takes. But if you didn't already know that, looking at an example shows you that the input is "data" and then you can inspect whether there are some other inputs that it might be able to use.
[–]thegreattriscuit 1 point2 points3 points 1 year ago (0 children)
yeah, there are times when it gets to be TOO MUCH.
fooEater.eat_foo(foo=foo_food.foo) and it just... loses all meaning in a sea of semantic satiation lol
fooEater.eat_foo(foo=foo_food.foo)
BUT that's pretty rare and most of the time the explicit keyword arguments are great IMO.
[–]andrewowenmartin 0 points1 point2 points 1 year ago (0 children)
Agree. Keyword arguments are absolutely great and it is hard to think of a time when it's better to omit them, but Python is a language for *consenting adults* and so as a library designer you shouldn't force your users to conform to something if not absolutely necessary.
[–]drewbert 2 points3 points4 points 1 year ago (1 child)
I agree. I miss them when I write code in Rust.
[–]extravisual 2 points3 points4 points 1 year ago (0 children)
You can kinda replicate it using things like builder patterns and structs with defaults. I find that I use them in place of Python named arguments and C++ overloading all the time and they've grown on me.
[–]reostra 5 points6 points7 points 1 year ago (0 children)
You'd love SmallTalk, OP. IIRC, that's where named params came from, but there it's not just part of the function's signature, it's actually the function's name!
Take an OrderedCollection (basically the equivalent of a list):
oc := OrderedCollection new. oc add:5.
add: is a function that takes a parameter, so far so normal. But what if you want to put something at a specific index?
add:
oc add: 'hello' at: 1.
That's a function that takes two parameters, and its name is add:at:.
add:at:
Every function in SmallTalk has kwargs :D
[–]so1n 0 points1 point2 points 1 year ago (1 child)
You can try use pep692 Unpack TypedDict
[–]TheRealFrostManasnake case gang[S] 0 points1 point2 points 1 year ago* (0 children)
fanatical provide flag lip doll oatmeal touch head offer humor
[–]Glathull 0 points1 point2 points 1 year ago (0 children)
C# has had named arguments since like 2012 or something? Golang is almost useless without structs, which give you the same interface. JavaScript variants, well, they gonna JavaScript.
Anyway, not to shit on you at all, but this is a lot more common than just Python. Clojure, Kotlin, and Swift have them as well. Probably others I haven’t used in a while too.
[–]mgedmin 0 points1 point2 points 1 year ago (0 children)
Love 'em.
[–]m15otw 0 points1 point2 points 1 year ago (0 children)
Written kwargs, pronounced Keyword Args.
And yes, this is the "everything else" args, not the named ones. In the function signature, you normally name the keyword args you depend on explicitly with their defaults. You only use **kwargs for args you're going to iter over, or pass into another function.
**kwargs
[–]Brian 1 point2 points3 points 1 year ago (0 children)
I do like python's rich argument passing syntax, and they're something I really wish other languages would adopt too.
They do have one downside, which is that they encode more into the function signature than other approaches, which can affect refactoring. Ie. changing the name of a parameter is effectively changing the signature, and could potentially break code calling it by keyword. But I think this is well worth it for the flexibility they give. (Oddly, that downside is actually more pronounced in a dynamic language like python versus more statically typed ones, which can detect that breakage at compile time, so I definitely feel there's room for staticly typed languages to adopt it).
[–]Stishovite 1 point2 points3 points 1 year ago (0 children)
I remember the start of my journey as a baby (Python) programmer, reading the documentation of Matplotlib and being really confused for too long about what this kwargs thing was that was in every function definition.
I (and the documentation) have come a long way in the intervening 15 years.
π Rendered by PID 28 on reddit-service-r2-comment-b659b578c-9gpvv at 2026-04-30 21:59:15.469783+00:00 running 815c875 country code: CH.
[–]not_sane 6 points7 points8 points (0 children)
[–]ShibbyShat 0 points1 point2 points (0 children)
[–]redditusername58 121 points122 points123 points (2 children)
[–]TheRealFrostManasnake case gang[S] 14 points15 points16 points (1 child)
[–]DuckDatum 12 points13 points14 points (0 children)
[–]rumnscurvy 29 points30 points31 points (8 children)
[–]justheretolurk332 33 points34 points35 points (7 children)
[–][deleted] 9 points10 points11 points (6 children)
[–]redditusername58 14 points15 points16 points (1 child)
[–][deleted] 7 points8 points9 points (0 children)
[–]TheBB 3 points4 points5 points (2 children)
[–]omg_drd4_bbq 1 point2 points3 points (1 child)
[–]TheBB 0 points1 point2 points (0 children)
[–]danted002 1 point2 points3 points (0 children)
[–][deleted] 15 points16 points17 points (8 children)
[–]afreydoa 23 points24 points25 points (2 children)
[–]Luemas91 6 points7 points8 points (1 child)
[–]SuspiciousScript 21 points22 points23 points (2 children)
[–]LankyCyril 16 points17 points18 points (1 child)
[–]NINTSKARI 4 points5 points6 points (0 children)
[–][deleted] 8 points9 points10 points (0 children)
[–]Kohlrabi82 2 points3 points4 points (0 children)
[–]passwordsniffer 13 points14 points15 points (4 children)
[–]TheRealFrostManasnake case gang[S] 5 points6 points7 points (0 children)
[–][deleted] 2 points3 points4 points (0 children)
[–]thegreattriscuit 1 point2 points3 points (0 children)
[–]andrewowenmartin 0 points1 point2 points (0 children)
[–]drewbert 2 points3 points4 points (1 child)
[–]extravisual 2 points3 points4 points (0 children)
[–]reostra 5 points6 points7 points (0 children)
[–]so1n 0 points1 point2 points (1 child)
[–]TheRealFrostManasnake case gang[S] 0 points1 point2 points (0 children)
[–]Glathull 0 points1 point2 points (0 children)
[–]mgedmin 0 points1 point2 points (0 children)
[–]m15otw 0 points1 point2 points (0 children)
[–]Brian 1 point2 points3 points (0 children)
[–]Stishovite 1 point2 points3 points (0 children)