我有一个Python问题。
假设我们有这个课程:
class Class:
def __init__(self, arg1, arg2, arg3):
self.arg1 = arg1
self.arg2 = arg2
self.arg3 = arg3
******* 这部分我不知道如何编码 **
def controls(self, instructions)
instructions[0] = instructions[1]
***************** ************
my_class = Class(arg1, arg2, arg3)
inputs = {"A":[self.arg1, value1],
"S":[self.arg2, value2],
"D":[self.arg3, value3]}
my_class.controls(inputs["A"])
所以dictinary(“输入”)映射键盘笔划。根据按下的键,我需要编辑my_class的一些属性。
我想要做的是:根据击键传递到def控件(self,instructions)需要编辑的值。因此,例如,如果用户按下“A”,那么我想将self.arg1从其现有的任何值更改为value1。同样,如果他按“S”,我想编辑另一个属性,等等。
所以,如果我这样做:
print instructions
我得到按键“A”:
[self.arg1, value1]
因此,例如,如果用户按下了“A”,“S”和“D”,一旦所有人都在这里解决了my_class应该是什么样子:
my_class.arg1 = value1
my_class.arg2 = value2
my_class.arg3 = value3
我做了各种尝试,但没有一个能够真正改变self.argX的值,它们都会给我一个错误或者没有做任何有用的事情。
我目前正在做一堆If / elif,但是它正在变长。
所以我的核心问题是:
如何传递参数指令[self.arg1,value1] 并让程序编辑我在指令[0] 中给出的任何属性并设置其值我在my_class中的指令[1] 中给出了什么价值?
编辑:删除以下评论后与问题核心无关的详细信息。
答案 0 :(得分:2)
我想你正在寻找这样的东西:
class DemoClassWhichSolvesProblemButWithoutUnnededFunctions(object):
def __init__(self, arg1, arg2, arg3):
self.arg1 = arg1
self.arg2 = arg2
self.arg3 = arg3
def controls(self, attribute_value_pair):
eval_string = attribute_value_pair[0] + " = " + str(attribute_value_pair[1])
exec(eval_string)
value1, value2, value3 = (1, 2, 3)
my_object = DemoClassWhichSolvesProblemButWithoutUnnededFunctions(0, 0, 0)
print "original values:", my_object.__dict__
inputs = {"A":["self.arg1", value1],
"S":["self.arg2", value2],
"D":["self.arg3", value3]}
my_object.controls(inputs["A"]) #my object, not my class...
my_object.controls(inputs["S"])
my_object.controls(inputs["D"])
#Even this one works:
my_object.controls( ("self.totally_new_attribute", "str('other value')") )
print "modified values:", my_object.__dict__
exec
接受一个字符串并将其视为此处写入的命令行 - 这可能会造成一些伤害!但我认为你正在寻找这样的解决方案......
答案 1 :(得分:0)
我不确定我的问题是否正确,但我认为您尝试做的只能通过以下方式之一完成:
提供要设置的属性的名称:
def controls(self, instructions):
setattr(self, instructions[0], instructions[1])
my_class = Class(arg1, arg2, arg3)
inputs = {"A": ['arg1', value1],
"S": ['arg2', value2],
"D": ['arg3', value3]}
my_class.controls(inputs["A"])
提供setter函数:
def attrsetter(attribute):
def realsetter(target, value):
setattr(target, attribute, value)
def controls(self, instructions):
instructions[0](self, instructions[1])
my_class = Class(arg1, arg2, arg3)
inputs = {"A": [attrsetter('arg1'), value1],
"S": [attrsetter('arg2'), value2],
"D": [attrsetter('arg3'), value3]}
my_class.controls(inputs["A"])
(我认为wiuld的第二个例子变得更简单了,但现在它写得更复杂了。但我现在暂时把它留在这里......)
在这两种情况下,我都会给出如何修改对象的命名属性的说明。
您尝试完成的方法不起作用,因为这需要指针,而Python中不存在这些指针。
现在我想起来了,还有一种方法可以做到。它很优雅,但也很复杂:
def controls(self, instructions):
# Call the given setter function which acts on the object it is given as a target.
instructions(self)
my_class = Class(arg1, arg2, arg3)
def set_input(mapping, letter, value):
def value_setter(func, value):
def replacement(target):
func(target, value)
return replacement
def outer_wrapper(func):
mapping[letter] = value_setter(func, value)
return outer_wrapper
inputs = {}
@set_input(inputs, "A", value1)
def set_arg1(target, value):
target.arg1 = value
@set_input(inputs, "S", value2)
def set_arg2(target, value):
target.arg2 = value
@set_input(inputs, "D", value3)
def set_arg3(target, value):
target.arg3 = value
my_class.controls(inputs["A"])
它以这种方式工作:每个setter函数都使用外部函数(装饰器创建函数)set_input()
返回的内容进行修饰:装饰器采用func
,将其包装到函数的另一层中并把它放入字典。