I have a class that inflates objects from rows found in a database (or another source, e.g. MongoDB, a CSV file, etc.). To set the object's properties, it does something like self.__dict__.update(**properties)
or obj.__dict__.update(**properties)
.
Is this considered Pythonic? Is this a good pattern that I should continue to use, or is this considered bad form?
-
1I don't know if it's Pythonic, but it's certainly more common to do it in dunder init.user16764– user167642013年08月12日 19:05:02 +00:00Commented Aug 12, 2013 at 19:05
-
Cf. Is self.__dict__.update(**kwargs) good or poor style? on Stack Overflow.jscs– jscs2013年08月12日 20:34:06 +00:00Commented Aug 12, 2013 at 20:34
1 Answer 1
In Python 3.3, a new type was added, types.SimpleNamespace()
, and in the documentation it is described thus:
The type is roughly equivalent to the following code:
class SimpleNamespace: def __init__(self, **kwargs): self.__dict__.update(kwargs) def __repr__(self): keys = sorted(self.__dict__) items = ("{}={!r}".format(k, self.__dict__[k]) for k in keys) return "{}({})".format(type(self).__name__, ", ".join(items))
Note the __init__
method of the type; you cannot get a better endorsement of the technique than the Python documentation.
-
Though
SimpleNamespace
is quite different from most types in that it doesn't have a fixed set of attributes.user7043– user70432013年08月12日 19:56:46 +00:00Commented Aug 12, 2013 at 19:56 -
7Well, speaking of the Python documentation, from docs.python.org/2/library/stdtypes.html "A special attribute of every module is
__dict__
. This is the dictionary containing the module’s symbol table. Modifying this dictionary will actually change the module’s symbol table, but direct assignment to the__dict__
attribute is not possible (you can writem.__dict__['a'] = 1
, which definesm.a
to be 1, but you can’twritem.__dict__ = {}
). Modifying__dict__
directly is not recommended," which is what initially prompted me to ask this question.skyler– skyler2013年08月12日 20:11:20 +00:00Commented Aug 12, 2013 at 20:11 -
@skyler: note that that only mentions the module namespace. The
globals()
function returns the same namespace, and there are usually better ways to solve problems than setting globals dynamically, hence the warning.Martijn Pieters– Martijn Pieters2015年03月14日 14:16:57 +00:00Commented Mar 14, 2015 at 14:16