Вы можете просто добавить функции поиска (методы) после создания класса:
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. В этом классе есть метод __init__()
, который не имеет параметра family
(установщики условий добавляются динамически во время выполнения, но добавляются в класс, а не в каждый экземпляр отдельно). Если необходимо создать Search
объекты с разными установщиками условий, тогда работает следующий вариант описанного выше метода (метод __init__()
имеет параметр 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']
Ссылка: http://docs.python.org/howto/descriptor.html#functions-and-methods
Если вам действительно нужны методы поиска, которые знают имя атрибута, в котором они хранятся, вы можете просто установить его в make_set_condition()
с помощью
set_cond.__name__ = option # Sets the function name
(незадолго до return set_cond
). Перед этим метод Search.name
имеет следующее имя:
>>> Search.price
<function set_cond at 0x107f832f8>
после установки его атрибута __name__
вы получите другое имя:
>>> Search.price
<function price at 0x107f83490>
Установка имени метода таким образом облегчает понимание возможных сообщений об ошибках, связанных с этим методом.
person
Eric O Lebigot
schedule
26.11.2011