On Sat, 02 Nov 2013 23:09:09 -0700, Peter Cacioppi wrote: > Python makes it very easy to turn a zero argument member function into a > property (hooray!) by simply adding the @property decorator. > > (Meme for well thought py feature - "Guido was here")
It is well-thought out, but it's also quite late in Python's history. Properties didn't get added until "new style classes" and descriptors, which was in version 2.2. I'm not sure if it's Guido to thank for them. > But the ease with which you can do this makes the "zero argument member > function or property" discussion trickier for me. > > Generally my sense here is there are two extremes > > 1-> the zero argument function is sort of factory-like. It potentially > has non-trivial run time, or it substitutes calling a class constructor > when building certain objects. 2-> it simply retrieves a stored value > (perhaps lazily evaluating it first) I normally go with something like this: Something with a significant overhead (e.g. memory or running time) should be a method. The fact that you have to call it is a hint that it may require non-trivial resources/time to perform. On the other hand, something that "feels" like it ought to be an inherent attribute of an object should be a property if you need it to be lazily calculated, or a standard attribute if you want to give direct access to it. For example, imagine an object representing a printable page. The paper size (A4, A3, foolscap, etc.) is an inherent attribute of a page, so it ought to be accessed using attribute notation: mypage.size If this is lazily generated, or if you want to protect the attribute with data validation, you should use a property. Otherwise, an ordinary data attribute is acceptable. (This isn't Java or Ruby, where data-hiding is compulsory :-) On the other hand, the Postscript image of the page is not inherent to the page, and it is also expensive to generate. So it ought to be generated lazily, only when needed, but using method notation: mypage.postscript() Page margins are intermediate. They feel kind of inherent to a page, but not exactly -- in a complex document, the margins may depend on the section you are in. Margins can vary depending on whether the page is at the left or the right. So page margins probably ought to be computed attributes. But they probably won't be terribly expensive to compute. So here I would again go with a property, assuming the page object knows whether it is on the left or the right, and which section it belongs to. But if somebody else decided that margins ought to be an explicit method, I wouldn't consider them wrong. It is a matter of personal taste. [...] > I also think that foo.size() implies that foo performs a count every > time it's called, and foo.size implies that the run time will amortize > to O(1) somehow (usually with lazy eval). So the implementation should > drive the property or not decision. I think that is reasonable. -- Steven -- https://mail.python.org/mailman/listinfo/python-list