[Tutor] question about "hiding" a function/method in a class

Mike Hansen mhansen at cso.atmel.com
Fri Jun 3 20:54:01 CEST 2005


> Subject:
> Re: [Tutor] question about "hiding" a function/method in a class
> From:
> Kent Johnson <kent37 at tds.net>
> Date:
> Fri, 03 Jun 2005 09:45:20 -0400
> 
> CC:
> tutor at 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


More information about the Tutor mailing list