在Python中使用字符串还是枚举检查对象类型
假设我有一个叫做 Tag 的对象,并且我有三种类型的标签,这些类型通过一个实例变量来表示,具体如下:
class Tag(object):
def __init__(self, name, type):
self.name = name
self.type = type
t1 = Tag("blue", "cold")
t2 = Tag("red", "warm")
t3 = Tag("black", "hot")
我只允许三种类型:冷、温和、热。那我是不是应该像这样检查它是否属于这三种类型呢?
if t1.type == "cold":
# do something
elif t1.type == "warm":
# do something else
else t1.type == "hot":
# do something even elser
还是说我应该创建一个类似枚举的对象,就像这个问题里提到的那样,
class Type:
COLD=1
WARM=2
HOT=3
然后像这样创建标签呢?
t1 = Tag("blue", Type.COLD)
我之所以问这个问题,是因为我听说比较字符串会消耗很多处理能力。虽然这些标签只有三到四个字母,但我可能会进行成千上万次这样的比较。你觉得为了判断一个对象的类型,创建枚举对象值得吗?还是说有更好的方法来实现我想做的事情呢?
4 个回答
2
我觉得不用太担心这个性能问题,除非通过性能分析发现确实有问题。如果你在使用集成开发环境(IDE),那么使用枚举的方式还有一个好处,就是可以检查拼写错误。
2
性能差异可能并没有那么大,值得你去担心。如果你对性能有疑虑,可以做个简单的测试。可以使用Python的 timeit 模块来测试这两种情况的性能。
0
在Python中,使用字典来处理不同情况通常比一堆if/elif/else语句要好。
所以:
class Tag(object):
def __init__(self, name, type):
self.name = name
self.type = type
self.dispatch = {"cold":Tag.process_cold, "warm":Tag.process_warm, "hot":Tag.process_hot}
def process(self):
self.dispatch[type](self)
def process_cold(self):
# do something
def process_warm(self):
# do something else
def process_hot(self):
# do something even elser
而且,稍微加一点代码就可以自动生成这个处理表:
def dispatchTable( klass, prefix ):
"""
Given a class and a method prefix string, collect all methods in the class
that start with the prefix, and return a dict mapping from the part of the
method name after the prefix to the method itself.
e.g. you have a class Machine with methods opcode_foo, opcode_bar.
create_dispatch_table( Machine, "opcode_" )
yields a dict
{ "foo": Machine.opcode_foo, "bar": Machine.opcode_bar }
"""
dispatch = {}
for name, fun in inspect.getmembers( klass, inspect.ismethod ):
if name.startswith(prefix):
# print "found %s.%s"%(k.__name__,name)
dispatch[ name.split(prefix)[1] ] = fun
return dispatch