Reputation: 501
I'm writing the code to take data from a html form and modify a database object. I only want to do a put() on the database object if there were changes, so I need to know if anything changed.
I've tried a couple of ways so far that I'll illustrate in code. They all use the following setup code:
def _addFormAttrToModel(self, obj, attr_name, new_attr):
if hasattr(obj, attr_name):
current_attr = getattr(obj, attr_name)
if current_attr == new_attr:
return False
setattr(obj, attr_name, new_attr)
return True
def addFormStringToModel(self, obj, attr_name):
new_attr = self.request.get(attr_name, None)
return self._addFormAttrToModel(obj, attr_name, new_attr)
The first uses or
to decide if any of the method calls return True.
updated=False
updated = self.addFormStringToModel(customer, "name") or updated
updated = self.addFormStringToModel(customer, "addr") or updated
updated = self.addFormStringToModel(customer, "phone") or updated
if updated:
customer.put()
Another form that I have experimented with uses a set:
results= set()
results.add( self.addFormStringToModel(customer, "name"))
results.add( self.addFormStringToModel(customer, "addr"))
results.add( self.addFormStringToModel(customer, "phone"))
if True in results:
customer.put()
What I'd really love to do is something like this:
updated = self.addFormStringToModel(customer, "name") and \
self.addFormStringToModel(customer, "addr") and \
self.addFormStringToModel(customer, "phone")
if updated:
customer.put()
However that stops execution after the first attribute that was updated. Is there a more pythonic way?
Upvotes: 1
Views: 27
Reputation: 14369
In order to remove the redundant code you should first define the list of fields to check:
fields_to_check = ['name', 'addr', 'phone']
Then you use a list aggregation to apply the method to all values:
updated = [self.addFormStringToModel(customer, field) for field in fields_to_check]
The any()
will tell if anyone of the results in the lis tis true:
if any(updated):
customer.put()
Upvotes: 1
Reputation: 599708
Use any
with a list:
updated = [self.addFormStringToModel(customer, "name"),
self.addFormStringToModel(customer, "addr"),
self.addFormStringToModel(customer, "phone")]
if any(updated):
You could make this shorter with a list comprehension:
updated = [self.addFormStringToModel(customer, field)
for field in ('name', 'addr' 'phone')]
if any(updated)
Upvotes: 2