Create objects from dictionary description - python

The Python MongoDB driver, PyMongo, returns results as dictionaries. I'm trying to figure out the best way to use such a dictionary in an object constructor.
Keep the dictionary as an attribute
self.dict = building_dict
Then each property of the building would be reachable through building.dict["property"].
A better attribute name could be used. Maybe a one-letter attribute. This doesn't look so elegant.
Parse dictionary to create attributes
self.name = building_dict['name']
self.construction_date = building_dict['construction_date']
...
In my model, the dictionaries can be pretty big but this task can be automated in the constructor to perform actions/checks on the values before or after the assignment.
Edit: The use of getters/setters is independent of options 1. and 2. above.
In solution 2., I'd avoid name collision between attributes and their getters by prefixing all dictionary keys by an underscore before making them attributes.
As a side-issue, the dictionary may contain the description of embedded documents, so the constructor should go through the whole dictionary to seek embedded documents that have their specific class in the code and instantiate those classes right away.
Update
I'll most probably use an ODM such as MongoEngine for my project and it will deal with those issues.
Outside of this specific use case (link with MongoDB, existing ODMs,...), the question is still relevant so I'm leaving below the best answer I could come up with.

The best you can do is to create an object. You can instantiate a classwith your dict like this:
building_dict = {'property': 4, 'name': 'my name'} # example dict
my_item = type('MyClass', (), building_dict) # instantiating class MyClass
You can access it afterwards like every other object:
print(my_item.property)
# 4
print(my_item.name)
# my name

My favorite solution so far stores elements as attributes and uses getters/setters:
class Building(object):
def __init__(self, dictionary):
# Check the values
# ...
# Find sub-dictionaries describing instances of another class
# stored as embedded documents in the base, call their
# constructor on sub-directories, then replace each sub-directory
# with the corresponding class instance.
# ...
# Set attributes from dictionary
for key in dictionary:
setattr(self, '_'+key, dictionary[key])
# Add default values if needed, etc.
# ...
# Usual getter/setter stuff
#property
def name(self):
try:
return self._name
except AttributeError as e:
# deal with missing name

Related

best way to created set of named objects in Python

I find myself frequently creating sets of named objects where each object has a unique name. I implement these as dicts whose keys are derived from myObject.name. But this feels a bit clunky to keep the name in two places.
My typical approach looks like this:
class NamedObject(object):
ITEMS = {}
def __init__(self, name, ...other arguments...):
self.name = name
...more initialization...
#classmethod
def create_named_object(cls, name, ...other arguments...):
obj = cls(name, ...other arguments...)
cls.ITEMS[name] = obj
#classmethod
def find_object_by_name(cls, name):
return cls.ITEMS.get(name, None)
#classmethod
def filter_objects(cls, predicate):
return [e for e in cls.ITEMS.values() if predicate(e)]
I know I could create a generalized class to handle this, but is there a more naturally Pythonic way to do this?
There is no more generalised support in the standard library, no, nor is there any more 'Pythonic' way to achieve this than using a dictionary.
What you are doing is providing an lookup table index, and indices generally require some duplication of data. You are trading memory for access speed. But indices are use-case specific and either trivially implemented with a mapping, or too specific to the application to be generalisable to the level that adding that to the language library makes sense.
At least in Python, the string value for the name is not actually duplicated; you just add more references to it; once from the instance and another time from the ITEMS dictionary.

Is there a way to access the underlying dict from a dict subclass?

I'd like to build a special dict class that has the option to export it's underlying dict as a whole (not just the individual items), i.e. something like this:
class CustomDict(dict):
def export(self):
return ??? # A dict instance
I know that I could simulate this behavior by simply building the export dict on the fly, or by storing the items in a separate class attribute in the first place, but I was wondering if there is a clean way of getting to the entire underlying dict directly. (Or am I overthinking this?)
There's no underlying dict instance. If you inherit from dict, CustomDict class is the dict class and has all dict's methods and properties. So what you want to do here is just pass the CustomDict instance wherever you wanted the dict to be exported to.

Sorting a list of inherited class instances by a class attribute dictionary Key

Is it possible to write a base class method to sort a list of class objects, stored as a static class variable, in a child class, by a key in a dictionary, that is an attribute of the class using sort or sorted or does a more elaborate sorting method need to be written?
I’m a python noob and I’ve attempted to write the “my_sorter” method using sort & sorted, trying at a lambda key definition, itemgetter, and attrgetter and am not sure if I am failing at the syntax to access these mixed nested structures or if it’s just not possible without writing a more elaborate sorting routine to deliberately shift entries around in the list.
Note that each child class has a static variable named “mindex” that identifies the “primary key” of its attribute dictionary (i.e. a unique value to sort by).
What would the my_sorter() method look like?
class Engine():
storage = []
#classmethod
def my_sorter(cls):
#sort cls.storage by cls.mindex
class Person(Engine):
mindex = 'Name'
def __init__(self, name):
self.attributes = {
'Name' : name,
}
class Meeting (Engine):
mindex = 'Date'
def __init__(self, date):
self.attributes = {
'Date' : date,
}
You don't show anywhere how your objects are ending up in the storage list, but assuming you have that working correctly (and you're not getting a mix of objects of different subclasses all in Engine.storage unexpectedly), the sorting should be pretty simple.
#classmethod
def my_sorter(cls):
return sorted(cls.storage, key=lambda obj: obj.attributes[cls.mindex])
I'm a little skeptical though about whether your Person and Meeting classes should be subclasses of Engine. That doesn't seem like an IS-A relationship to me. Perhaps it would make more sense if I knew the whole project design.

what is the dict class used for

Can someone explain what the dict class is used for? This snippet is from Dive Into Python
class FileInfo(dict):
"store file metadata"
def __init__(self, filename=None):
self["name"] = filename
I understand the assignment of key=value pairs with self['name'] = filename but what does inheriting the dict class have to do with this? Please help me understand.
If you're not familiar with inheritance concept of object-oriented programming have a look at least at this wiki article (though, that's only for introduction and may be not for the best one).
In python we use this syntax to define class A as subclass of class B:
class A(B):
pass # empty class
In your example, as FileInfo class is inherited from standard dict type you can use instances of that class as dictionaries (as they have all methods that regular dict object has). Besides other things that allows you assign values by key like that (dict provides method for handing this operation):
self['name'] = filename
Is that the explanation you want or you don't understand something else?
It's for creating your own customized Dictionary type.
You can override __init__, __getitem__ and __setitem__ methods for your own special purposes to extend dictionary's usage.
Read the next section in the Dive into Python text: we use such inheritance to be able to work with file information just the way we do using a normal dictionary.
# From the example on the next section
>>> f = fileinfo.FileInfo("/music/_singles/kairo.mp3")
>>> f["name"]
'/music/_singles/kairo.mp3'
The fileinfo class is designed in a way that it receives a file name in its constructor, then lets the user get file information just the way you get the values from an ordinary dictionary.
Another usage of such a class is to create dictionaries which control their data. For example you want a dictionary who does a special thing when things are assigned to, or read from its 'sensor' key. You could define your special __setitem__ function which is sensitive with the key name:
def __setitem__(self, key, item):
self.data[key] = item
if key == "sensor":
print("Sensor activated!")
Or for example you want to return a special value each time user reads the 'temperature' key. For this you subclass a __getitem__ function:
def __getitem__(self, key):
if key == "temperature":
return CurrentWeatherTemperature()
else:
return self.data[key]
When an Class in Python inherits from another Class, it means that any of the methods defined on the inherited Class are, by nature, defined on the newly created Class.
So when FileInfo inherits dict it means all of the functionality of the dict class is now available to FileInfo, in addition to anything that FileInfo may declare, or more importantly, override by re-defining the method or parameter.
Since the dict Object in Python allows for key/value name pairs, this enables FileInfo to have access to that same mechanism.

How to create properties at runtime with Python?

So I'm trying to figure out if what I want to do is even possible. I am writing some test code for an application, and I have objects that contain properties representing some of the elements we have in the interface for our product. What I want to do is be able to pass in the application runner and the data object to a new class and have it dynamically generate a set of accessor properties based upon a subset of the properties in the data object. My idea so far:
Create a subclass of property that includes metadata required for extracting the extra information from the interface
Refactor the existing data objects to use the new property subclass for relevant fields in the UI
Create a new generator class that accepts the UI driver object and the data object that
reflects the data object to get a list of all the members of it that are of the new property subclass type
stores the information from the UI based upon the metadata in the property subclass to members of the generator class instance (planning on using setattr)
create properties at run time to make the members created in (b) read-only and provide an interface consistent with existing code (ie using .[name] instead of .[name]())
I think I have everything figured out except step 3c. Is there a way to create properties dynamically at runtime? Any help would be greatly appreciated.
Not sure that's what you want. But you could define dynamic read-only property with getattr and setattr method. Here is an example:
class X(object):
data = {'x' : 123, 'y' : 456}
def __getattr__(self, name):
if name in self.data:
return self.data[name]
raise AttributeError(name)
def __setattr__(self, name, value):
if name in self.data:
return None
return super(X, self).__setattr__(name, value)
a = X()
print a.x, a.y
a.x = 0
print a.x

Categories