Puteți adăuga pur și simplu funcțiile (metodele) de căutare după ce clasa este creată:
class Search: # The class does not include the search methods, at first
def __init__(self):
self.conditions = {}
def make_set_condition(option): # Factory function that generates a "condition setter" for "option"
def set_cond(self, value):
self.conditions[option] = value
return self
return set_cond
for option in ('price', 'name'): # The class is extended with additional condition setters
setattr(Search, option, make_set_condition(option))
Search().name("Nice name").price('$3').conditions # Example
{'price': '$3', 'name': 'Nice name'}
PS: această clasă are o metodă __init__()
care nu are parametrul family
(setatorii de condiții sunt adăugați dinamic în timpul execuției, dar sunt adăugați la clasă, nu la fiecare instanță separat). Dacă trebuie create Search
obiecte cu stabilitori de condiții diferiți, atunci următoarea variație a metodei de mai sus funcționează (metoda __init__()
are un parametru family
):
import types
class Search: # The class does not include the search methods, at first
def __init__(self, family):
self.conditions = {}
for option in family: # The class is extended with additional condition setters
# The new 'option' attributes must be methods, not regular functions:
setattr(self, option, types.MethodType(make_set_condition(option), self))
def make_set_condition(option): # Factory function that generates a "condition setter" for "option"
def set_cond(self, value):
self.conditions[option] = value
return self
return set_cond
>>> o0 = Search(('price', 'name')) # Example
>>> o0.name("Nice name").price('$3').conditions
{'price': '$3', 'name': 'Nice name'}
>>> dir(o0) # Each Search object has its own condition setters (here: name and price)
['__doc__', '__init__', '__module__', 'conditions', 'name', 'price']
>>> o1 = Search(('director', 'style'))
>>> o1.director("Louis L").conditions # New method name
{'director': 'Louis L'}
>>> dir(o1) # Each Search object has its own condition setters (here: director and style)
['__doc__', '__init__', '__module__', 'conditions', 'director', 'style']
Referință: http://docs.python.org/howto/descriptor.html#functions-and-methods
Dacă într-adevăr aveți nevoie de metode de căutare care știu despre numele atributului în care sunt stocate, îl puteți seta pur și simplu în make_set_condition()
cu
set_cond.__name__ = option # Sets the function name
(chiar înainte de return set_cond
). Înainte de a face acest lucru, metoda Search.name
are următorul nume:
>>> Search.price
<function set_cond at 0x107f832f8>
după ce setați atributul __name__
, obțineți un alt nume:
>>> Search.price
<function price at 0x107f83490>
Setarea numelui metodei în acest fel face posibile mesaje de eroare care implică metoda mai ușor de înțeles.
person
Eric O Lebigot
schedule
26.11.2011