Maybe this isn’t a good example of OOP?
Does it suggest the author perhaps doesn't fully understand principles behind loosely coupled OO code?
If is_sold is an attribute of book, the class shouldn't have a sell method, but a mark_as_sold.
The action of selling is not the responsibility of a Book. Baking it into Book will create tight coupling between areas of the code (product and commerce) that should be loosely coupled. The "commerce" side may change for reasons unrelated to the "product" side. Keep'em separated.
And if we think for a minute, is_sold should not be a Book attribute in the first place. It seems to me this piece of information should be handled somewhere else related to inventory, not by the Book itself.
There should be a ProductEntry class, for instance. It could have a product_type and product_sku attributes, for example, pointing to a Book.
Even here, is_sold shouldn't be an attribute, but a method. It would have an availability_status attribute.
func is_sold(self) { return self.status == ProductStatus.SOLD }
Ultimately, the inventory code should not care that it's a Book or whatever.
The logic of whether it's available or not doesn't belong to the product itself. What if someone bought, but returned it? Maybe it will be available for shipping tomorrow and the store wants to start reselling it already? Is it the Book responsibility to track that? No way.