Python: 传递字符串在类中引用 (self.string)
我有一个关于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"])
这个字典(“inputs”)用来记录键盘按键。根据按下的键,我需要修改我这个类的一些属性。
我想做的是:把需要根据按键修改的值传给 def controls(self, instructions)
。比如说,如果用户按下“A”,那么我想把 self.arg1
的值改成 value1
,无论它现在是什么值。类似的,如果按下“S”,我想把另一个属性改成另一个值,等等。
所以如果我这样做:
print instructions
当按下“A”键时,我得到:
[self.arg1, value1]
举个例子,如果用户按下了“A”、“S”和“D”,在所有这些都处理完后,我的类应该是这样的:
my_class.arg1 = value1
my_class.arg2 = value2
my_class.arg3 = value3
我尝试了很多方法,但都没能成功改变 self.argX
的值,要么出错,要么没什么用。
我现在在用很多的 If/elif,但这样写太长了。
所以我最核心的问题是:
我怎么能把 instruction[self.arg1, value1] 作为参数传入,让程序根据 instruction[0] 修改我类中的某个属性,并把它的值设置为 instruction[1] 中的值呢?
编辑:根据下面的评论,去掉了一些与问题核心无关的细节。
2 个回答
我不太确定我是否理解你的问题,但我觉得你想做的事情只能通过以下几种方式来实现:
提供要设置的属性名称:
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"])
提供设置函数:
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"])
(我原以为第二个例子会更简单,但写下来后发现其实更复杂。不过我先把它留在这里…)
在这两种情况下,我都给出了如何修改对象中指定属性的说明。
你尝试的方法是行不通的,因为这需要指针,而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"])
它的工作原理是这样的:每个设置函数都被一个外部函数(创建装饰器的函数)set_input()
返回的装饰器装饰,这个装饰器接收一个func
,将其包裹在另一个函数层中,并把这个层放入字典中。
我想你是在寻找类似这样的东西:
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
这个命令会把你给的字符串当成命令行来执行,这样可能会带来一些风险!不过我猜你是在找这样的解决方案……