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

_______________________________________________
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor

Reply via email to