我想迭代选择的类实例并将成员变量设置为等于值。我可以通过以下方式访问成员值:
for foo in range(1,4): #class members: pv1, pv2, pv3
bar[foo] ='{0}'.format(locals()['pv' + str(foo)+'.data'])
然而,当我尝试设置/改变这样的值时:
for foo in range(1,4): #class members:
'{0}'.format(locals()['pv' + str(foo)+'.data']) = bar[foo]
我明显得到错误:
SyntaxError: can't assign to function call
我尝试过几种方法来完成它但没有成功。我在实际代码中使用了比3更多的实例(大约250个),但我的问题很清楚。我查看了几个堆栈溢出问题,例如Automatically setting class member variables in Python - 和 - dynamically set an instance property / memoized attribute in python?但似乎没有人回答这个问题。在C ++中,我只使用指针作为中介。 Pythonic的做法是什么?
答案 0 :(得分:0)
attr是一个有效的分配目标,即使它是表达式结果的attr。
for foo in range(1,3):
locals()['pv' + str(foo)].data = bar[foo]
另一位开发人员写了几行关于setattr()的内容,主要是关于如何避免它。
除非属性名称是动态的,否则
setattr
是不必要的。但他们并没有说出原因。你是否介意详细阐述为什么你把你的答案从setattr()转移出来?
在这种情况下,attr是data
,它永远不会改变,所以在
for i in range(1, 3):
setattr(locals()['pv' + str(i)], 'data', bar[i])
做同样的事情,这里不需要setattr
。 .data =
形式既足够好又通常是首选 - 它更快,意图更清晰 - 这就是我改变它的原因。另一方面,如果你需要在每个循环中更改attr名称,那么你需要它,例如。
for i in range(1,3):
setattr(locals()['pv' + str(i)], 'data' + str(i), bar[i])
上面的代码设置名为data1
,data2
,data3
的attrs,展开,相当于
pv1.data1 = bar[1]
pv2.data2 = bar[2]
pv3.data3 = bar[3]
我原本认为你的问题需要做这样的事情,这就是我首先使用setattr的原因。一旦我对它进行了测试并使其正常工作,我就发布它而没有注意到setattr
不再需要。
如果attr名称在运行时发生了变化(其他开发人员的意思是" dynamic")那么你就不能使用点语法,因为你有一个字符串对象而不是静态标识符。使用setattr的另一个原因可能是在表达式中需要副作用。与C不同,赋值是Python中的语句。但像setattr
这样的函数调用是表达式。
答案 1 :(得分:0)
以下是创建一个类的示例,该类明确允许通过索引或属性调用进行访问以更改内部变量。这通常不会被推广为良好的编程和#39;虽然。它没有明确定义人们应该与底层变量进行交互的规则。
__getattr__()
函数的定义允许分配(object).a
。
__getitem__()
函数的定义允许赋值
(object)['b']
class Foo(object):
def __init__(self, a=None,b=None,c=None):
self.a=a
self.b=b
self.c=c
def __getattr__(self, x):
return self.__dict__.get(x, None)
def __getitem__(self, x):
return self.__dict__[x]
print
f1 = Foo(3,2,4)
print 'f1=', f1.a, f1['b'], f1['c']
f2 = Foo(4,6,2)
print 'f2=', f2.a, f2['b'], f2['c']
f3 = Foo(3,5,7)
print 'f3=', f3.a, f3['b'], f3['c']
for x in range(1, 4):
print 'now setting f'+str(x)
locals()['f'+str(x)].a=1
locals()['f'+str(x)].b=1
locals()['f'+str(x)].c=1
print
print 'f1=', f1.a, f1['b'], f1['c']
print 'f2=', f2.a, f2['b'], f2['c']
print 'f3=', f3.a, f3['b'], f3['c']
结果是
f1= 3 2 4
f2= 4 6 2
f3= 3 5 7
now setting f1
now setting f2
now setting f3
f1= 1 1 1
f2= 1 1 1
f3= 1 1 1