Не знаю, будет ли это иметь смысл, но ...
Я пытаюсь динамически назначать методы объекту.
#translate this
object.key(value)
#into this
object.method({key:value})
Чтобы быть более конкретным в моем примере, у меня есть объект (который я не писал), давайте назовем его мотором, у которого есть набор общих методов, состояние и некоторые другие. Некоторые принимают словарь в качестве аргумента, а некоторые - список. Чтобы изменить скорость двигателя и увидеть результат, я использую:
motor.set({'move_at':10})
print motor.status('velocity')
Объект motor затем форматирует этот запрос в строку JSON-RPC и отправляет его демону ввода-вывода. Моторный объект python не заботится о аргументах, он просто обрабатывает JSON-форматирование и сокеты. Строки move_at и скорость - это только два из сотен допустимых аргументов.
Вместо этого я хотел бы сделать следующее:
motor.move_at(10)
print motor.velocity()
Я бы хотел сделать это в общем виде, поскольку у меня так много разных аргументов, которые я могу передать. Чего я не хочу делать, так это:
# create a new function for every possible argument
def move_at(self,x)
return self.set({'move_at':x})
def velocity(self)
return self.status('velocity')
#and a hundred more...
Я провел некоторые поиски по этому вопросу, которые предположили, что решение лежит в лямбдах и метапрограммировании, двух предметах, которые я не смог осознать.
UPDATE:
На основе кода от user470379 я придумал следующее ...
# This is what I have now....
class Motor(object):
def set(self,a_dict):
print "Setting a value", a_dict
def status(self,a_list):
print "requesting the status of", a_list
return 10
# Now to extend it....
class MyMotor(Motor):
def __getattr__(self,name):
def special_fn(*value):
# What we return depends on how many arguments there are.
if len(value) == 0: return self.status((name))
if len(value) == 1: return self.set({name:value[0]})
return special_fn
def __setattr__(self,attr,value): # This is based on some other answers
self.set({attr:value})
x = MyMotor()
x.move_at = 20 # Uses __setattr__
x.move_at(10) # May remove this style from __getattr__ to simplify code.
print x.velocity()
выход:
Setting a value {'move_at': 20}
Setting a value {'move_at': 10}
10
Спасибо всем, кто помог!