It is an object, not a function. The difference is important: the thing you get with m = hashlib.md5()
is a structure in memory that has an internal state. Each update()
call updates that state (hence the name).
You can imagine the object has a kind of box. Each update()
call accumulates input bytes in that box. When you want to obtain the hash value, the MD5 mathematical function is applied to the complete box contents. That way, it does not matter whether you put the bytes in the box as one or two or seventeen successive calls; what matters is that you ultimately sent all the bytes in the box.
Technically, MD5MD5 processes input data by blocks of 512 bits (64 bytes) and maintains a running state consisting of 128 bytes (16 bytes) along with a counter (the number of bytes that were hashed is used at the end of the function evaluation). Thus, a practical MD5 implementation will indeed contain a "box" (usually called a "buffer") that can accumulate up to 64 bytes; whenever 64 bytes have been accumulated, they are processed as per the MD5 specification, and the box is emptied. That way, the object remains small in RAM, even if you hash gigabytes of data.
Reading the specificationspecification to implement your own MD5 code is a very nice programming exercise, that is very enlightening. I recommend that you try it.