> Subject: > Re: [Tutor] question about "hiding" a function/method in a class > From: > Kent Johnson <[EMAIL PROTECTED]> > Date: > Fri, 03 Jun 2005 09:45:20 -0400 > > CC: > tutor@python.org > > > Mike Hansen wrote: > >> class DBField(object): >> def __init__(self, fieldName): >> self.fieldName = fieldName >> self.type = "" >> self.size = 0 >> self.notNull = False >> self.unique = False >> self.references = "" >> self.default = "" >> >> def printField(self): >> self.fieldStr = " %s %s" %(self.fieldName, self.type) >> if self.size > 0: >> self.fieldStr = "%s(%s)" %(self.fieldStr, self.size) >> if self.notNull: >> self.fieldStr = "%s NOT NULL" %self.fieldStr >> if self.unique: >> self.fieldStr = "%s UNIQUE" %self.fieldStr >> if self.default: >> self.fieldStr = "%s DEFAULT %s" %(self.fieldStr, >> self.default) >> # if self.references >> return self.fieldStr >> >> def __getattr__(self, attrname): >> if attrname == "fieldStr": >> return self.printField() >> else: >> raise AttributeError, attrname >> --------------------------- >> >> I was wondering if I should "hide" the printField function, so I or >> someone else won't do x.printField() in the main program but use the >> x.fieldStr attribute. If so, how would I do that, def >> __printField(self):? How would I call it from __getattr__? I know I'm >> not really hiding it ;just mangling it. On the other hand, I guess it >> doesn't matter. What do you think? > > > Python programmers tend to take the attitude "We're all adults here" > towards things like this. We use conventions to put warning labels where > appropriate, then trust the client programmer to do what is right for them. > > So, to answer your direct question, yes, you could call the method > __printField(), which nominally hides the name from other modules, or > _printField(), which by convention marks the method as for internal use > only (a warning label). You would call it from __getattr__() as > __printField() or _printField(). (A quick experiment would have answered > this part of the question.) > > However, for your particular usage of dynamically computing the value of > a field, there is a better way to do this - use a property. > > class DBField(object): > def _printField(self): > ... > > # Create a read-only fieldStr attribute whose value is computed by > _printField() > fieldStr = property(_printField) > > # Remove _printField so it can't be called directly > del _printField > > > A few more comments: > - The name _printField() is a bit of a misnomer since nothing is > printed; _getFieldStr() might be a better name. > - Another, simpler way to do this is to define __str__() instead of > _printField() and fieldStr; then clients can just call str(field) to get > the string representation. This will work well if you don't need any > other string representation. > - Of course you could also just define getFieldStr() and forget about > the fieldStr attribute entirely. This is also a very simple, > straightforward approach. > > Kent >
Doh, I forgot about properties! If I had read a little more in Learning Python on the page with __getattr__, I might have noticed properties. I might go with the "Simple is better than complex" approach using getFieldStr(). I agree that printField wasn't sounding like a good name. Thanks for the comments. Mike _______________________________________________ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor