On 03/09/16 06:55, Sharad Singla wrote: > What's the correct way to define/access methods of a member variable in a > class pointing to an object?
Steven has already given you a long and comprehensive answer based on pragmatic python programming. But since you use the term "correct" I'll give you an alternative view based on generic/theoretical OOP practice. The caveat is that theoretical best practice does not always transfer to the real world and you must compromise. Just ensure you compromise in the full knowledge that it is a compromise... 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. BUT... that does not mean you should expose all of foo's interface as methods of Bar. After all Bar should only have an instance of Foo to support its own behaviour. In other words whatever methods you call on Bar may manipulate Foo *behind the scenes*. (If Foo is not being used by Foo's methods then what is it doing in Bar at all?!) So if you really want to change some aspect of Bar's Foo instance then it should only be happening as a result of you doing something to your Bar instance. If you really, really need to modify the Foo instance directly (and this should be fairly rare) the "correct" OOP way to do that is for Bar to provide a getFoo() accessor method and for you to fetch the Foo instance and then manipulate it directly b = Bar() f = b.getFoo() f.someMethod() f.someAttribute = 42 # etc... b.setFoo(f) # put it back when you are done. This then keeps Bar's use of foo hidden (you don't know if Bar is returning a reference to its internal Foo or creating a copy for you to play with.) In python we tend to use direct access rather than getFoo/setFoo. We'd just say b.foo, but that means if Bar wants to return a copy of Foo then it needs to implement foo as a property. So to summarise, the Law of Demeter states that you should provide foo access via Bar's interface but the expectation is that you only create operations(methods) on Bar that modify Foo as a part of that operation, not that you simply expose all of Foo via Bar. One huge exception to all of this is where you create Bar explicitly as a manager of Foo objects and its role is only to provide access to Foos (an example might be an object pool in a server application). But in that case there probably should be get/set methods which will do some sanity checking before handing over a Foo to you to play with, or storing a foo that you have been messing about with. HTH -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos _______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor