On Sat, Sep 03, 2016 at 02:51:22PM +0100, Alan Gauld via Tutor wrote: [...] > The first thing to do is point out that what you > are asking about is the Law of Demeter on OOP. > See Wikipedia for a full description. In essence > it says that the user of an object should not > directly access that object's internal attributes/state. > So ideally you only access foo via a call to a method of > Bar.
That's a very important answer too, thanks Alan for reminding me of it, but remember that the Law of Demeter is more of a guideline, and we should understand it, not just blindly quote it. One classic example of the Law Of Demeter is: "If you want your dog to come to you, don't talk to your dog's legs, talk to the dog." class Dog: ... fido = Dog() # I want the dog to come here. fido.left_front_leg.lift() fido.left_front_leg.forward() fido.left_front_leg.down() fido.right_back_leg.lift() ... Arggh, no, that's terrible! That violates the Law Of Demeter, and you shouldn't expect your users to do that. The caller shouldn't have to care about *how the dog walks*. fido.command("come here boy!") Or perhaps: fido.heel() whatever is most appropriate. The details of how the dog walks is encapsulated inside the Dog class. Another classic example is of a transaction where the paper boy gives you a newspaper and you pay him a dollar: newspaper = paperboy.get_paper() paperboy.balance += 1.0 customer.trousers.wallet.balance -= 1.0 No! Would you really let the paperboy reach into your trousers, grab your wallet, open it up, and take money out? Again, another Demeter violation. Better to re-write your Customer class: class Customer: def pay(self, amount): if amount > self.wallet.balance: raise ValueError self.wallet.balance -= amount return amount paperboy.receive(customer.pay(1.0)) But sometimes the Law Of Demeter should not apply. Sometimes you are expected to tinker with the internals of an object. car = Car() # replace the engine with a bigger one car.engine = Engine("800 horsepower of throbbing nitro-fueled POWER") car.engine.inject(nitro=True) but as I suggested in an earlier email, that mostly applies when the attribute is a fairly simple object like a list, a dict, or similar. -- Steve _______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor