Yet another question about class property.

Dave Angel davea at ieee.org
Wed May 20 06:00:20 EDT 2009


Jim Qiu wrote:
> Hi everyone,
>
> Following is the code i am reading, i don't see anywhere the declaration of
> Message.root object,
> Where is it from?
>
> #bots-modules
> import bots.botslib as botslib
> import bots.node as node
> from bots.botsconfig import *
>
>
> class Message(object):
>     ''' abstract class; represents a edi message.
>         is subclassed as outmessage or inmessage object.
>     '''
>     def __init__(self):
>         self.recordnumber=0                #segment counter. Is not used for
> UNT of SE record; some editypes want sequential recordnumbering
>
>     @staticmethod
>     def display(records):
>         '''for debugging lexed records.'''
>         for record in records:
>             t = 0
>             for veld in record:
>                 if t==0:
>                     print '%s    (Record-id)'%(veld[VALUE])
>                 else:
>                     if veld[SFIELD]:
>                         print '        %s    (sub)'%(veld[VALUE])
>                     else:
>                         print '    %s    (veld)'%(veld[VALUE])
>                 t += 1
>
>     def get(self,*mpaths):
>         ''' query tree (self.root) with mpath; get value (string); get None
> if not found.'''
>         if self.root.record is None:
>             raise botslib.MpathRootError('get("%s"): "root" of incoming
> message is empty; either split messages or use inn.getloop'%(str(mpaths)))
>         return self.root.get(*mpaths)
>
>     def getnozero(self,*mpaths):
>         ''' like get, returns None is value is zero (0) or not numeric.
>             Is sometimes usefull in mapping.'''
>         if self.root.record is None:
>             raise botslib.MpathRootError('get("%s"): "root" of incoming
> message is empty; either split messages or use inn.getloop'%(str(mpaths)))
>         return self.root.getnozero(*mpaths)
>
>     def getindicator(self,ind,*mpaths):
>         ''' like get, returns None is value is zero (0) or not numeric.
>             Is sometimes usefull in mapping.'''
>         if self.root.record is None:
>             raise botslib.MpathRootError('get("%s"): "root" of incoming
> message is empty; either split messages or use inn.getloop'%(str(mpaths)))
>         return self.root.getindicator(ind,*mpaths)
>
>     def getcount(self):
>         ''' count number of nodes in self.root. Number of nodes is number of
> records.'''
>         return self.root.getcount()
>
>     def getcountoccurrences(self,*mpaths):
>         ''' count number of nodes in self.root. Number of nodes is number of
> records.'''
>         count = 0
>         for value in self.getloop(*mpaths):
>             count += 1
>         return count
>
>     def getcountsum(self,*mpaths):
>         ''' return the sum for all values found in mpath. Eg total number of
> ordered quantities.'''
>         if self.root.record is None:
>             raise botslib.MpathRootError('get("%s"): "root" of incoming
> message is empty; either split messages or use inn.getloop'%(str(mpaths)))
>         return self.root.getcountsum(*mpaths)
>
>     def getloop(self,*mpaths):
>         ''' query tree with mpath; generates all the nodes. Is typically
> used as: for record in inn.get(mpath):
>         '''
>         if self.root.record:    #self.root is a real root
>             for terug in self.root.getloop(*mpaths): #search recursive for
> rest of mpaths
>                 yield terug
>         else:   #self.root is dummy root
>             for childnode in self.root.children:
>                 for terug in childnode.getloop(*mpaths): #search recursive
> for rest of mpaths
>                     yield terug
>
>     def put(self,*mpaths):
>         if self.root.record is None and self.root.children:
>             raise botslib.MpathRootError('put("%s"): "root" of outgoing
> message is empty; use out.putloop'%(str(mpaths)))
>         return self.root.put(*mpaths)
>
>     def putloop(self,*mpaths):
>         if not self.root.record:    #no input yet, and start with a
> putloop(): dummy root
>             if len(mpaths) == 1:
>                 self.root.append(node.Node(mpaths[0]))
>                 return self.root.children[-1]
>             else: #TODO: what if self.root.record is None and len(mpaths) >
> 1?
>                 raise botslib.MpathRootError('putloop("%s"): mpath too
> long???'%(str(mpaths)))
>         return self.root.putloop(*mpaths)
>
>     def sort(self,*mpaths):
>         if self.root.record is None:
>             raise botslib.MpathRootError('get("%s"): "root" of message is
> empty; either split messages or use inn.getloop'%(str(mpaths)))
>         self.root.sort(*mpaths)
>
>     def normalisetree(self,node):
>         ''' The node tree is check, sorted, fields are formated etc.
>             Always use this method before writing output.
>         '''
>         #~ node.display()
>         #~ print 'normalisetree'
>         self._checktree(node,self.defmessage.structure[0])
>         self._canonicaltree(node,self.defmessage.structure[0])
>
>     def _checktree(self,tree,structure):
>         ''' checks tree with table:
>             -   all records should be in table at the right place in
> hierarchy
>             -   for each record, all fields should be in grammar
>             This function checks the root of grammar-structure with root of
> node tree
>         '''
>         if tree.record['BOTSID'] == structure[ID]:
>             #check tree recursively with structure
>             self._checktreecore(tree,structure)
>         else:
>             raise botslib.MessageError('(Root)record %s of %s not in table
> %s'%(tree.record['BOTSID'],tree.record,self.defmessage.grammarname))
>
>     def _checktreecore(self,node,structure):
>         ''' recursive
>         '''
>         deletelist=[]
>         self._checkfields(node.record,structure)
>         if node.children and not LEVEL in structure:
>             if self.ta_info['checkunknownentities']:
>                 raise botslib.MessageError('Record "%s" in message has
> children, but structure of grammar "%s" not. Found gg
> "%s".'%(node.record['BOTSID'],self.defmessage.grammarname,node.children[0].record['BOTSID']))
>             node.children=[]
>             return
>         for childnode in node.children:          #for every node:
>             for structure_record in structure[LEVEL]:           #search in
> grammar-records
>                 if childnode.record['BOTSID'] == structure_record[ID]:   #if
> found right structure_record
>                     #check children recursive
>                     self._checktreecore(childnode,structure_record)
>                     break    #check next mpathnode
>             else:   #checked all structure_record in grammar, but nothing
> found
>                 if self.ta_info['checkunknownentities']:
>                     raise botslib.MessageError('Record "%s" in message not
> in structure of grammar "%s". Whole record:
> "%s".'%(childnode.record['BOTSID'],self.defmessage.grammarname,childnode.record))
>                 deletelist.append(childnode)
>         for child in deletelist:
>             node.children.remove(child)
>
>
>     def _checkfields(self,record,structure_record):
>         ''' checks for every field in record if field exists in
> structure_record (from grammar).
>         '''
>         deletelist=[]
>         for field in record.keys():          #all fields in record should
> exist in structure_record
>             for grammarfield in structure_record[FIELDS]:
>                 if grammarfield[ISFIELD]:    #if field (no composite)
>                     if field == grammarfield[ID]:
>                         break
>                 else:   #if composite
>                     for grammarsubfield in grammarfield[SUBFIELDS]:   #loop
> subfields
>                         if field == grammarsubfield[ID]:
>                             break
>                     else:
>                         continue
>                     break
>             else:
>                 if self.ta_info['checkunknownentities']:
>                     raise botslib.MessageError('Field "%s" does not exist in
> record: %s'%(field,structure_record[MPATH]))
>                     #~ raise botslib.MessageError('Field "%s" does not exist
> in record: %s'%(field,structure_record[ID]))       #alt voor MPATH
>                     #~ raise botslib.MessageError('Field "%s" does not exist
> in record: %s'%(field,structure_record[FIELDS]))   #folder, text is too long
>                 deletelist.append(field)
>         for field in deletelist:
>             del record[field]
>
>     def _canonicaltree(self,node,structure,headerrecordnumber=0):
>         ''' For nodes: check min and max occurence; sort the nodes conform
> grammar
>             For fields: check M/C; format the fields.
>         '''
>         sortednodelist = []
>         self._canonicalfields(node.record,structure,headerrecordnumber)
>  #write the fields
>         if LEVEL in structure:
>             for structure_record in structure[LEVEL]:  #for structure_record
> of this level in grammar
>                 count = 0                           #count number of
> occurences of record
>                 for childnode in node.children:            #for every node
> in mpathtree; SPEED: delete nodes from list when found
>                     if childnode.record['BOTSID'] != structure_record[ID]:
> #if it is not the right NODE":
>                         continue
>                     count += 1
>
>  self._canonicaltree(childnode,structure_record,self.recordnumber)
> #use rest of index in deeper level
>                     sortednodelist.append(childnode)
>                 if structure_record[MIN] > count:
>                     raise botslib.MessageError('Record "%s": mandatory but
> not present.'%(structure_record[MPATH]))
>                 if structure_record[MAX] < count:
>                     raise botslib.MessageError('Record "%s": occures to
> often (%s times).'%(structure_record[MPATH],count))
>             node.children=sortednodelist
>             if hasattr(self,'do_queries'):
>                 self.do_queries(node,structure)
>
>     def
> _canonicalfields(self,noderecord,structure_record,headerrecordnumber):
>         ''' For fields: check M/C; format the fields. Field are not sorted
> here (a dict can not be sorted)
>         '''
>         #~ print noderecord
>         for grammarfield in structure_record[FIELDS]:
>             if grammarfield[ISFIELD]:    #if field (no composite)
>                 value = noderecord.get(grammarfield[ID],'')
>                 #~ print 'check field',grammarfield,value
>                 if not value:
>                     if grammarfield[MANDATORY] == 'M':
>                         raise botslib.MessageError('Record "%s": mandatory
> field "%s" not filled.'%(structure_record[MPATH],grammarfield[ID]))
>                     elif not grammarfield[MINLENGTH]:   #if minlength=0
>                         continue
>                 noderecord[grammarfield[ID]] =
> self._formatfield(value,grammarfield,structure_record)
>             else:               #if composite
>                 compositefilled = False
>                 for grammarsubfield in grammarfield[SUBFIELDS]:   #loop
> subfields to see if one of them is there
>                     if noderecord.get(grammarsubfield[ID],''):
>                         compositefilled = True
>                 if not compositefilled:
>                     if grammarfield[MANDATORY]=='M':
>                         raise botslib.MessageError('Record "%s": mandatory
> composite "%s" not filled.'%(structure_record[MPATH],grammarfield[ID]))
>                     continue
>                 for grammarsubfield in grammarfield[SUBFIELDS]:   #loop
> subfields
>                     value = noderecord.get(grammarsubfield[ID],'')
>                     #~ print 'check subfield',grammarsubfield,value
>                     if not value:
>                         if grammarsubfield[MANDATORY]=='M':
>                             #~ print 'Record "%s": mandatory subfield "%s"
> not filled: "%s".'%(structure_record[MPATH],grammarsubfield[ID],noderecord)
>                             raise botslib.MessageError('Record "%s":
> mandatory subfield "%s" not filled:
> "%s".'%(structure_record[MPATH],grammarsubfield[ID],noderecord))
>                         else:
>                             continue
>                     noderecord[grammarsubfield[ID]] =
> self._formatfield(value,grammarsubfield,structure_record)
>                     #~ print 'fill',grammarfield[ID]
>
> Thanks in advance.
>
> Jim
>
>   
Unlike your previous question, this attribute is not referenced in 
__init__().  That, plus the comment about being an abstract class, leads 
me to guess that the derived classes are required to define this 
attribute.  That's one of the characteristics of an abstract class;  
some of the details are missing, and intended to be supplied by a child 
class.

What do the docs for this abstract class say?  If they don't discuss how 
to implement a concrete class, they're sadly lacking.




More information about the Python-list mailing list