How to change the value of an attribute using QgsFeature in PyQGIS?

Answering your two questions:

  1. You can change your feature values from the layer object, no need to access the dataProvider().

  2. Yes, you can use the iterator in a for loop.

Check the code below:

layers = QgsMapLayerRegistry.instance().mapLayersByName('my_line') 
layer = layers[0]
it = layer.getFeatures()

layer.startEditing()
for feat in it:
  layer.changeAttributeValue(feat.id(), 2, 30)

layer.commitChanges()

This updates the third (index 2) field value to 30 for all layer features.


Note: As you pointed out, for some reason the QgsFeature object cannot update feature values, although the API says it can.


Yes, but you have to know the index of the field:

QgsFeature::setAttribute(int field,const QVariant & attr )  

You can get the fields using QgsFeature::fields and then iterate through them until you find the one you want or QgsFeature::attribute(const QString & name ) to find the field index by name.

The reason for QVariant is that the setAttribute can take Integer, Float, Date and Text types. QgsFeature.attribute(name) returns a variant also of type int if the attribute is found and something else if it can't be found.. be aware of this in your code. A try..except block would be warranted, try to convert to int and except if type is not int.

It is possible that your feature doesn't support this method. Another method that I have employed is QgsVectorLayer::changeAttributeValue:

self.canvas.currentLayer().changeAttributeValue(UpdateFeatureID,FieldToUpdate,self.CurrentWidget.text(),True)

This tells the layer to update a specific feature and specific attribute. In the example case the value comes from a widget.