Python:处理大量可能不存在的属性的首选方法?
编辑: 最初的问题涉及PyQt和matplotlib,而真正的问题太复杂了,无法解释,所以我试图将其简化,但没有真正解决。但从回答中我了解到,实际的问题可能不在我最初认为的地方。我想这就是学习编程的意义所在 谢谢大家Python:处理大量可能不存在的属性的首选方法?,python,attributes,set,Python,Attributes,Set,编辑: 最初的问题涉及PyQt和matplotlib,而真正的问题太复杂了,无法解释,所以我试图将其简化,但没有真正解决。但从回答中我了解到,实际的问题可能不在我最初认为的地方。我想这就是学习编程的意义所在 谢谢大家 我正面临一个困扰我的文体问题。我试着使它尽可能的一般化,以便对其他人也有帮助。考虑下面的类: class Values(object): def __init__(self): self.first_attr = None self.sec
我正面临一个困扰我的文体问题。我试着使它尽可能的一般化,以便对其他人也有帮助。考虑下面的类:
class Values(object):
def __init__(self):
self.first_attr = None
self.second_attr = None
self.third_attr = None
self.fourth_attr = None
def set_first(self, data):
self.first_attr = data
def set_second(self, data):
self.second_attr = data
def set_third(self, data):
self.third_attr = data
def set_fourth(self, data):
self.fourth_attr = data
def add_to_three(self):
attrs = (
self.first_attr,
self.second_attr,
self.third_attr,
)
self._add_one(attrs)
def add_to_two(self):
attrs = (
self.second_attr,
self.fourth_attr,
)
self._add_one(attrs)
def _add_one(self, attrs):
for attr in attrs:
if attr:
attr += 1
我们有一类价值观。该类总共可以有4个不同值的属性。每个值都可以用setter设置(没有使用decorator来简化事情)
还有两种方法具有属性的元组,它们的值应该增加。这些值在运行时之前确定
我们还有一个方法“add_one”,如果设置了这些属性,它会将一个添加到它接收的属性中。否则什么也不会发生
现在,让我们创建几个实例并设置一些值
first_values = Values()
first_values.set_second = 5
first_values.add_to_three()
second_values = Values()
second_values.set_first = 2
second_values.set_third = 4
second_values.add_to_two()
这很好,因为“add_one”方法检查是否设置了每个属性
但是如果我有50个属性呢?我不喜欢把它们都设为零。另外,我不喜欢在那些add_to_方法中显式地编写元组
如果通过仅更改Values类来处理大量属性,那么最合适的处理方法是什么?此代码应允许您创建具有开放式属性集的对象,包括元组属性,然后增加其内容
class Values():
def __init__(self, *attrs):
'''each element in attrs is a tuple(attrname, value)'''
if attrs is not None:
for a in attrs:
n, v = a
setattr(self, n, v)
def add_one(self, attr):
a = getattr(self, attr, None)
if a:
if isinstance(a, tuple):
setattr(self, attr, tuple(e + 1 for e in a))
else:
setattr(self, attr, a + 1)
v = Values(('x', 1), ('y', 2), ('z', 3), ('t', (7, 8, 9)))
print('Initial values:', v.x, v.y, v.z, v.t)
v.add_one('x')
print('X modified:', v.x, v.y, v.z, v.t)
v.add_one('t')
print('T modified:', v.x, v.y, v.z, v.t)
v.add_one('a')
print('Tried to modify non-existent attribute "a"', v.x, v.y, v.z, v.t)
结果:
>>> import attr
Initial values: 1 2 3 (7, 8, 9)
X modified: 2 2 3 (7, 8, 9)
T modified: 2 2 3 (8, 9, 10)
Tried to modify non-existent attribute "a" 2 2 3 (8, 9, 10)
>>>
此代码将允许您动态创建对象,其中每个实例包含大量可能属性的子集,并操作每个实例的属性。我想您需要一个字典
data = {'two': 4}
attrs = ['one','two','three']
for attr in attrs:
if data.has_key(attr):
data[attr] += 1
else:
data[attr] = 1 # this assumes all new attributes had an effective value of zero when they didn't exist
# it seems like you want nonesxistant attributes to remain nonexistant
# so just remove the else case
顺便说一句,为什么要使用setter呢?“但是如果我有50个属性呢?”为什么会有一个只有50个属性的类?这将是一个可怕的气味。是的,我可以删除它们,使代码更短。说得对。我真的很难理解你想做什么。我觉得要么你让你的代码泛化来问这个问题,而这是没有意义的,要么你把事情复杂化了,可能应该在上面使用一个值和函数的
列表。我只是想知道什么时候开始使用继承,例如基本上只是因为属性的数量。谢谢Jonathan!尽管我的例子很糟糕,也没有真正给出我真正的问题的正确想法,但不知何故你还是接受了这个想法。我考虑了getattr/setattr,它看起来比设置为None更像python,比如说10个可能需要或不需要的属性。谢谢