我已经开始学习python的第一步了,我正在尝试开始使用类。
到目前为止,我有这个简化版本:
class ThingsInTheFridge(object):
def __init__(self):
self.milk = False
self.yogurt = False
self.bread = True
self.umbrella = True
我班上将会有大约30件事情,每件事都被分配为真或假(我已经缩短了这个问题的清单。)
分配它们的最有效方法是什么?
我已经考虑过这个但是它似乎没有改善,特别是当列表增加时:
self.milk, self.yogurt = False, False
编辑: 我或许应该提到类中有其他项目(我省略了它们因为我认为不重要):
class ThingsInTheFridge(object):
def __init__(self):
self.milk = False
self.yogurt = False
self.bread = True
self.umbrella = True
self.bulb = "maker name"
self.shoes = 2
答案 0 :(得分:4)
如果你真的关心运行时效率,你几乎肯定会在错误的地方找工作。如果初始化你的成员需要太长时间(这是非常不可能的......但如果你发现并发现这是热点...),正确的答案是使用__slots__
,而不是改变初始化的方式。
如果您关心程序员效率(可读性,以及可写性较小),您可以随时执行此操作:
self.milk = self.yogurt = False
如果你想更动态地做事,你可以用setattr
做这样的事情,但我不推荐它:
class ThingsInTheFridge(object):
false_things = ('bread', 'umbrella')
true_things = ('milk', 'yogurt')
def __init__(self):
for thing in ThingsInTheFridge.false_things:
setattr(self, thing, False)
for thing in ThingsInTheFridge.true_things:
setattr(self, thing, True)
我不推荐它的原因是,如果你需要在这个级别动态地做事,你也可能需要在 access 级别动态,这意味着你真的应该是使用dict
或set
,如Lattyware所述。
你也可以在类式系统之上过度自我构建原型风格的OO系统,或创建一个基于类信息等初始化实例的元类,但是,这句话的开头表示那将会过火。
答案 1 :(得分:4)
我认为这会显示存储数据模型的问题。您可能希望使用类似集合的数据结构,而不仅仅是属性。
例如:
items = {"milk", "yogurt", "bread", "umbrella"}
stored = set()
然后只需将您想要的内容存储在stored
集中。集合具有非常快的成员资格检查性能,因此要检查,您可以简单地执行"milk" in stored
。
如果你真的想保留你拥有的界面,你可以使用__getattr__()
覆盖你在要求属性时获得的动作:
def ___getattr__(self, item):
return item in self.stored
这会将False
返回到不在冰箱内的任何物品,如果您需要它只能回复可能的物品,这很容易就可以完成:
def ___getattr__(self, item):
if item not in self.items:
raise AttributeError
return item in self.stored
当然,也可以进行设置:
def __setattr__(self, item, value):
if item in self.items:
if value:
self.stored.add(item)
else:
self.stored.remove(item)
else:
...
另一种选择是对True
/ False
的谴责 - 我不能说我认为要么特别好,要么更适合你的项目。只要使用最适合你的东西。
答案 2 :(得分:1)
我认为您的主要关注点应该是可读性和基础数据结构。
像这样的东西是非常易读的(并且可能),因为你可以通过滚动自己来实现高性能:
from collections import Counter
class Fridge(object):
def __init__(self,things,name):
self.things=Counter(things)
self.wanted=set()
self.name=name
def look(self, thing):
print 'There are {} {} in {}'.format(self.things[thing],thing,self.name)
def stare_inside(self):
cathave=sorted([(co,it) for it,co in self.things.items() if co])
print '{} items in {}:'.format(len(cathave),self.name)
for i, item in enumerate(cathave,1):
print ' {}: {} -- {}'.format(i,item[1],item[0])
def shop(self):
shop_list=[it for it,co in self.things.items() if co==0]
for item in shop_list:
del self.things[item]
shop_list.extend(list(self.wanted))
self.wanted=set()
print "shopping list:"
for i, item in enumerate(sorted(shop_list),1):
print ' {}: {}'.format(i,item)
def consume(self,thing,count):
if self.things[thing]>=count:
self.things[thing]-=count
else:
print 'Not enough {} to consume {} -- {} in the {}.'.format(
thing,count,self.things[thing],self.name)
self.wanted.add(thing)
def stock(self,things):
self.things+=Counter(things)
现在尝试一下:
>>> kitchen=Fridge({'coke':2, 'whole milk':1,'ketchup':1, 'anchovies':24},'kitchen fridge')
>>> kitchen.look('coke')
There are 2 coke in kitchen fridge
>>> kitchen.stock({'coke':1,'pepsi':2,'banana':3})
>>> kitchen.stare_inside()
6 items in kitchen fridge:
1: ketchup -- 1
2: whole milk -- 1
3: pepsi -- 2
4: banana -- 3
5: coke -- 3
6: anchovies -- 24
>>> kitchen.consume('red bull',22)
Not enough red bull to consume 22 -- 0 in the kitchen fridge.
>>> kitchen.consume('coke',3)
>>> kitchen.consume('whole milk',1)
>>> kitchen.stare_inside()
4 items in kitchen fridge:
1: ketchup -- 1
2: pepsi -- 2
3: banana -- 3
4: anchovies -- 24
>>> kitchen.shop()
shopping list:
1: coke
2: red bull
3: whole milk
这是基于collection module Counter class.你不太可能想出一些更快的原生Python。
答案 3 :(得分:0)
使用一组字符串而不是单个标志成员实际上可能会更好。像下面这样的东西可能更适合你似乎想要做的事情。
class ThingsInTheFridge:
"""I represent a collection of items in a refrigerator.
I contain a few things by default. You can add and remove items as
well as test for membership.
>>> things = ThingsInTheFridge()
>>> object() in things
False
>>> things.store_item('foo')
>>> 'foo' in things
True
"""
def __init__(self):
self._items = set()
self.store_item('bread')
self.store_item('umbrella')
def store_item(self, item):
"""Add an item to the fridge.
:param item: the item to add.
Items are coerced into strings and normalized before they are
added to the internal list.
>>> things = ThingsInTheFridge()
>>> things.store_item(False)
>>> 'false' in things
True
>>> 'FALSE' in things
True
>>> False in things
True
"""
self._items.add(str(item).lower())
def __contains__(self, item):
"""Check if an item is in the fridge.
:param item: item to check for.
Items are coerced into strings and normalized to match the processing
in :py:meth:`store_item`.
>>> things = ThingsInTheFridge()
>>> things.store_item('Milk')
>>> 'Milk' in things, 'milk' in things, 'MiLk' in things
(True, True, True)
"""
return str(item).lower() in self._items