On Wed, Aug 6, 2014 at 7:15 PM, Steven D'Aprano <st...@pearwood.info> wrote: > On Wed, 06 Aug 2014 12:07:58 +1000, Chris Angelico wrote: > >> On Wed, Aug 6, 2014 at 10:49 AM, Steven D'Aprano >> <steve+comp.lang.pyt...@pearwood.info> wrote: >>> A >>> plethora of argument-less methods is a code smell -- that doesn't mean >>> it's *necessarily* a bad idea, but the class design really needs a >>> careful review. >> >> There are plenty of no-argument mutator methods, where the name of the >> method (and the target object, obviously) is all the info you need. You >> can clear() or copy() something with any more info, reverse() a list, >> pop() from a list, etc. > > They don't have to be mutator methods. The same applies to string methods > like upper(), lower(), isalpha() and many others. > > I'm not sure if you're agreeing or disagreeing with me.
Agreeing with your primary point, disagreeing with this subpoint. > All these > examples shouldn't be treated as properties either. This should be > grounds for being slapped with a large herring: > > mydict.clear # returns None, operates by side-effect Wholeheartedly agree. These should NOT be properties. A property should not mutate state, normally (I can imagine exceptions, but they are *definitely* code smell, unless they're doing basic logging or something). What I disagree with is that argument-less methods, even a plethora thereof, are *themselves* code smell. Mutator methods, and the string methods that construct a "this string only different" result (which in many ways are the immutable object's equivalent of mutators), will often take no args, and are most definitely not properties, but IMO aren't code smell. Something like isalpha() is borderline, but making upper() a property implies that, conceptually, the upper-case version of a string is an attribute the string already has, rather than something that you construct from that string. It's debatable, but IMO it makes perfect sense to keep that as a method - and it's fine for it to take no args other than the object it's working on. > As I said, zero-argument (one-argument, if you count self) > methods are a code smell, not an error. As is so often the case in > programming, the fundamental sin here is *coupling* -- zero-argument > methods are bad if they require coupling to temporary attributes which > exist only to communicate an argument to the method. > > In other words, one of the sins of zero-argument methods is the same as > that of zero-argument functions. We wouldn't write this: > > def double(): > return number_to_operate_on*2 > > number_to_operate_on = 23 > print double() > number_to_operate_on = 42 > print double() > > > Turning it into a method on an instance, and turning the global into a > "per instance global" (instead of per module, or application-wide) > doesn't make it any better. But if it were written as: class float(float): pass # allow more attributes on float def double(self): return self*2 float.double = double number = float(23) print(number.double()) Then it's not hidden global state any more, but it's still a zero-argument method. Is that really just as bad? Surely it's the same as "print(double(number))"? ChrisA -- https://mail.python.org/mailman/listinfo/python-list