general class functions

bruno modulix onurb at xiludom.gro
Wed Nov 3 00:27:07 CET 2004


Kent Johnson a écrit :
> syd wrote:
> 
>> In my project, I've got dozens of similar classes with hundreds of
>> description variables in each.  In my illustrative example below, I
>> have a Library class that contains a list of Nation classes.  In one
>> case, I might want a Library class with only Nations of with the
>> continent variable "Europe", and so I'll do something like
>> library.getContinent('Europe') which will return a Library() instance
>> with only European nations.  Similarly, I could also want a Library()
>> instance with only 'small' size nations.
>>
>> My question follows: is there a way I can make a general function for
>> getting a subclass with my specific criteria?  For instance, can I
>> pass in an equivalence test or something like that?  I have hundreds
>> of variables like "nation", "continent", and so forth, and do want to
>> write a separate "get______" function for each.
> 
> 
> You can use getattr to read the Nation attributes by name. Add this 
> method to Library:
>   def getMatches(self,attribute, value):
>     library=Library()
>     for nation in self.list:
>       if getattr(nation, attribute) == value:
>         library.add(nation)
>     return library
> 
> Now you can call
> print library.getMatches('continent', 'Europe').getNameList()
> print library.getMatches('continent', 'Europe').getMatches('size', 
> 'small').getNameList()

<just for the fun...>

You could make it even more simple - and avoid creating useless 
instances of Library and Nation - with keyword arguments:

class Library:
   [...]
   def getAll(self, **kwargs):
     library=Library()
     for nation in self.list:
       keep = True
       for attribute, value in kwargs.items():
         if not getattr(nation, attribute) == value:
           keep = false
           break
       if keep :
         library.add(nation)
     return library

print library.getAll(continent='Europe').getNameList()
print library.getAll(continent='Europe', size='small').getNameList()

This is and 'and' search, you could also have an 'or' search method:

   def getAny(self, **kwargs):
     library=Library()
     for nation in self.list:
       for attribute, value in kwargs.items():
         if getattr(nation, attribute) == value:
           library.add(nation)
           break
     return library

print library.getAny(continent='Europe', size='small').getNameList()

and then a more generic search:
   def getMatches(self, op, **kwargs):
     fun = {'or': self.getAny, 'and' : self.getAll}.get(op)
     return fun(**kwargs):

print library.getMatches('and',
                          continent='Europe',
                          size='small').getNameList()

print library.getMatches('or',
                          continent='Europe',
                          size='small').getNameList()

</just for the fun...>

Bruno



More information about the Python-list mailing list