简体   繁体   中英

How to use a list of attributes of SimpleNamespace instead of list of dict keys?

Recently, I started using SimpleNamespace as an alternative to dict for more OOP-like syntax.

Let's say I have a dict:

test = { 'a':1, 'b':2, 'c':3 }

And I have this function:

def get_average(test: dict, keys : list):
    return statistics.mean([test[x] for x in keys])

Which takes a dict and a list of keys and returns an average of all the values of those keys for said dict.

I convert this dict into SimpleNamespace like so:

test_as_namespace = SimpleNamespace(**test)

How do I implement the get_average function for this SimpleNamespace syntax without revealing the underlying dict structure?

Also note, I am not a professional in Python so if you smell wrong code, please suggest a better way (data structure / type) to solve this problem (OOP-like dicts).

SimpleNamespace is just a wrapper for the dict so you can just pass the dict property.

test = { 'a':1, 'b':2, 'c':3 }

def get_average(d):
    return statistics.mean(d.values())

test_as_namespace = SimpleNamespace(**test)

avg = get_average(test_as_namespace.__dict__)

Moreover, if you aren't going to use dicts at all then you can simply create your SimpleNamespace object directly:

your_namespace_obj = SimpleNamespace(a=1, b=2, c=3)

Answer 1

There is no better way - use a dict, it's core purpose is intended for just this kind of function.

Or, if you prefer the SimpleNamespace generally for other reasons, then convert to it, but pull the underlying dict back out for the purpose of this particular filter function.

Answer 2

If you really still want to find an alternative. You can use the built-in function __getattribute__ on your SimpleNamespace object to directly pull the value for the corresponding attributes.

def get_average(test: dict, keys : list):
    return statistics.mean([test.__getattributes__(x) for x in keys])

I suspect __getattributes__ is just using the underlying dict in the background to access the attribute values, though. There may be some additional overhead going this route - not sure.

Discussion

The dict class in Python is a hash-map, which is generally the fastest/cleanest way to access a specific value that corresponds to a given key. The keys must be hashable, which means they will be unique, so each key will only be in the dict one time and will correspond to a single value (which could be a non-hashable object that has multiple values in it, like a list).

So, computationally, or from the point of view of elegance of programming (or Pythonicity), there is no reason to move away from a dict. In the given function, the core hash-map functionality of a dict is what is needed. ie given certain keys, we need to do some function on the corresponding values.

If this does not answer the question directly, then please clarify what is 'better' about another format, such as SimpleNamespace - at least for the filtering function. Or, clarify why a dict would not be good for production. I think it would be hard to find any production code using Python that doesn't use dicts.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM