Thanks for you patience, Dave. Obviously i have not got used to the python philosophy.
Following you guide, i implemented the following code, and you are absolutely right. #!/usr/bin/python #coding:utf-8 class Parent(object): def __init__(self): pass def displayAttrOfSubClass(self): print self.attrFromChild class Child(Parent): def __init__(self): self.attrFromChild = 'Hi, Everyone, Java does this support this trick!' childObj = Child() childObj.displayAttrOfSubClass() Python can use in the parent class a variable only instantiated by a sub-class, is this a point of advance of technique of Python? Jim On Wed, May 20, 2009 at 6:00 PM, Dave Angel <da...@ieee.org> wrote: > 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. > >
-- http://mail.python.org/mailman/listinfo/python-list