Harmful side effects for different namedtuples wit

2019-05-11 18:38发布

问题:

Consider the following function:

>>> from collections import namedtuple
>>> def make_thing(**kwargs):
...     ThingClass = namedtuple('ThingClass', kwargs.keys())
...     return ThingClass(**kwargs)
...
>>> make_thing(x=1,y=2,z=3)
ThingClass(y=2, x=1, z=3)
>>> make_thing(a=4,b=5,c=6)
ThingClass(a=4, c=6, b=5)
>>>

The function calls namedtuple to produce a "temporary" class with field names the same as the input dict's keys. Then it returns an instance with the values filled in.

My question is whether or not this has any particular pitfalls since the typename argument to namedtuple is always the same, even though there are different field names. For example, if namedtuple created a class in the background that would get overridden by doing this, then I could see some potentially strange behavior cropping up later. Are there any side effects/gotchas for doing this?

Optional info:

If you're wondering what the heck I'm doing that would possess me to write this code, I've got an ORM that's returning somewhat dict-like results. I've seen the objects behave strangely with assignment, and I'd really rather not pass objects around that may or may not have the capability to modify my database (depending on how the query code is written). Trying to maintain DTO objects for every single query seems like too much hassle, as does trying to make all my queries compatible with a small set of DTOs. So I came up with this as a quick, simple way of passing around clearly immutable objects where I can write code like dto.a. It's essentially a dynamic, on the fly DTO generator. It also buys me a rather nice repr implementation for when I'm debugging.

回答1:

There are no pitfalls, the classes are not registered centrally.

All you see is the classes using self.__name__ to generate a representation string. The classes themselves only live on as .__class__ references on the instances as the local name is cleared up when the make_thing() function finishes.