My answer will mainly talk about API design for using dicts vs. keyword args. But this also applies to individual use {...} vs. dict(...) .
The bottom line: be consistent. If most of your code will refer to 'bar' as a string - save it in the string {...} ; if you usually refer to it with the bar identifier, use dict(bar=...) .
Limitations
Before talking about style, note that the syntax of the bar=42 keyword works only for strings and only if they are valid identifiers. If you need arbitrary punctuation, spaces, unicode - or even non-string keys - the question is completed => the syntax {'bar': 42} will work.
It also means that when developing an API, you must allow full dicts, not just keyword arguments - unless you are sure that only strings and only valid identifiers are allowed. (Technically, update(**{'spaces & punctuation': 42}) works, but it's ugly, and numbers / tuples / unicode won't work.)
Note that dict() and dict.update() combine both APIs: you can pass one dict, you can pass args keywords, and you can even pass both (the later one, I think, is undocumented). Therefore, if you want to be nice, allow both:
def update(self, *args, **kwargs): """Callable as dict() - with either a mapping or keyword args: .update(mapping) .update(**kwargs) """ mapping = dict(*args, **kwargs)
This is especially recommended for a method named .update() to follow the rule of least surprise.
Style
I am pleased to distinguish between internal and external lines. By internal, I mean arbitrary identifiers that mean something only inside the program (variable names, object attributes) or, possibly, between several programs (DB columns, XML attribute names). They are usually visible only to developers. Outer strings are for human consumption.
[Some Python encoders (including me) abide by the convention of using 'single_quotes' for inner strings vs. "Double quotes" for outer strings. This is definitely not universal.]
Your question is about the proper use of simple words (the Perl term) - syntactic sugars that allow you to omit quotation marks in internal lines altogether. Some languages ββ(especially LISP) allow them widely; Pythonic's ability to use simple words is access to attributes - foo.bar and keyword arguments - update(bar=...) .
The stylistic dilemma here is " Are your lines internal enough to look like identifiers? "
If the keys are external strings, the answer is definitely NO:
foo.update({"The answer to the big question": 42})
If the keys are for Python identifiers (e.g. object attributes), I would say YES:
foo.update(dict(bar=42))
If the keys refer to identifiers outside of your Python program, such as XML attribute names or database column names, using simple words may be a good or bad choice - but you better choose one style and be consistent.
Consistency is good because there is a psychological barrier between identifiers and strings. It exists because lines rarely cross it - only when using introspection for metaprogramming. And syntax highlighting only enhances it. Therefore, if you read the code and see a green 'bar' in one place and a black foo.bar in second place, you cannot immediately establish a connection.
Another important rule: Bars are good if they are (mostly) fixed . For example. if you refer to the fixed columns of the database mainly to your code, then using descriptors to refer to them may be nice; but if half the time of the column is a parameter, it is better to use rows.
This is because the parameter / constant is the most important difference that people associate with the identifier / string barrier. The difference between column (variable) and "person" (constant) is the most readable way to convey this difference. Creating both identifiers will blur the difference, as well as a syntactic backtrack - you will need to use **{column: value} and getattr(obj, column) , etc. Lot.