Difference between setattr and object manipulation in python/django

前端 未结 2 1606
南旧
南旧 2021-01-30 17:24

I have the following model:

class Ticket(models.Model):
    title = models.CharField()
    merged_to = models.ForeignKey(\"self\", related_name=\'merger_ticket\'         


        
2条回答
  •  隐瞒了意图╮
    2021-01-30 17:41

    This is more of a Python question.

    Python is very dynamic language. You can code things (classes) ahead of time, or Python allows you to create classes completely dynamically at run-time. Consider the following example of a simple vector class. You can create/code the class ahead of time like:

    class MyVector(object):
        x = 0
        y = 0
    

    or you can create the class dynamically by doing:

    fields = {'x':0, 'y':0}
    MyVector = type('MyVector', (object,), fields)
    

    The main difference between the methods is that for one you know the class attributes ahead of time, whereas for the second method as you can imagine, you can programmatically create the fields dictionary, therefore you can create completely dynamically class(es).

    So when you know the attributes of the class ahead of time, you can set class attributes using the object notation:

    instance.attribute = value
    

    Keep in mind that that is equivalent to:

    instance.__setattr__("attribute", value)
    

    However there are scenarios where you don't know the class attributes you will need to manipulate ahead of time. This is where you can use __setattr__ function. However it is not recommended practice. So instead the recommendation is to use Python's build-in method setattr which internally calls the __setattr__ method:

    setattr(instance, attribute, value)
    

    Using this approach you can set attributes you don't know ahead of time or you can even loop of some dict and set values from dict:

    values = {
        'title': 'This is edit title',
        ...
    }
    for k, v in values.items():
        setattr(ticket, k, v)
    

    Not sure why the regular notation did not work for. It probably has nothing to do with the method you used to set attributes.

提交回复
热议问题