用于检查Python中对象类型的字符串与枚举
假设我有一个名为Tag的对象,我有三种类型的标记,由一个实例变量以下面的方式表示用于检查Python中对象类型的字符串与枚举,python,string,performance,types,enums,Python,String,Performance,Types,Enums,假设我有一个名为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") 假设我只允许三种类型:冷、热和热。是否最好去检查一下它是
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
t1 = Tag("blue", Type.COLD)
或者我应该创建一个类似枚举的对象
而是像这样创建标签
if t1.type == "cold":
# do something
elif t1.type == "warm":
# do something else
else t1.type == "hot":
# do something even elser
t1 = Tag("blue", Type.COLD)
我问这个问题的原因是因为我听说比较字符串需要很大的处理能力,即使这些是3个或4个字母长的短单词,我也可能会对这些类型进行成千上万次的比较。您认为创建枚举对象来确定对象的类型是否值得,如我上面所示的示例所示?或者有没有更好的方法来完成我正在尝试的任务?性能差异可能不足以让您担心。如果你关心性能,你应该做一个简单的测试。使用Python的模块测试这两种情况的性能。性能差异可能不足以让您担心。如果你关心性能,你应该做一个简单的测试。使用Python的模块来测试这两种情况的性能。除非分析表明这确实是一个问题,否则我不会担心它的性能。如果您使用的是IDE,enum方法有打字检查的好处。除非分析表明这确实是一个问题,否则我不会担心它的性能。如果您使用的是IDE,enum方法有打字检查的好处。在python中,使用字典进行分派通常比使用大量If/elif/else更有利 因此: 再加上一小段代码就可以自动生成调度表:
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
在python中,使用字典进行分派通常比使用大量if/elif/else更为有利 因此: 再加上一小段代码就可以自动生成调度表:
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
我将使用一种组合方法——将“enum”作为标记类的一部分,接受一个字符串进行初始化,然后将其转换。另外,您可以使用dict来创建分派表,而不是使用一堆if/else分支
class Tag(object):
COLD = 0
WARM = 1
HOT = 2
def __init__(self, name, temp):
if temp.upper() not in ('COLD', 'WARM', 'HOT'):
raise ValueError("Invalid temp: %r" % temp)
self.temp = getattr(self, temp.upper())
self.name = name
def process(self):
func = self.temp_dispatch[self.temp]
func(self) # NOTE: have to pass 'self' explicitly
def cold(self):
print('brrr')
def warm(self):
print('ahhh')
def hot(self):
print('ouch!')
temp_dispatch = {COLD:cold, WARM:warm, HOT:hot}
tag = Tag('testing', 'Cold')
tag.process()
我将使用一种组合方法——将“enum”作为标记类的一部分,接受一个字符串进行初始化,然后将其转换。另外,您可以使用dict来创建分派表,而不是使用一堆if/else分支
class Tag(object):
COLD = 0
WARM = 1
HOT = 2
def __init__(self, name, temp):
if temp.upper() not in ('COLD', 'WARM', 'HOT'):
raise ValueError("Invalid temp: %r" % temp)
self.temp = getattr(self, temp.upper())
self.name = name
def process(self):
func = self.temp_dispatch[self.temp]
func(self) # NOTE: have to pass 'self' explicitly
def cold(self):
print('brrr')
def warm(self):
print('ahhh')
def hot(self):
print('ouch!')
temp_dispatch = {COLD:cold, WARM:warm, HOT:hot}
tag = Tag('testing', 'Cold')
tag.process()
我认为枚举解决方案的一个优点是,它清楚地说明了允许的值是什么。如果你接受任意字符串,我会说这“更容易出错,也更难记录你的词汇”。例如,
logging
模块将这种解决方案用于日志级别(例如,logging.DEBUG
,logging.INFO
,等等)。我认为枚举解决方案的一个优点是它可以清楚地显示允许的值。如果你接受任意字符串,我会说这“更容易出错,也更难记录你的词汇”。例如,logging
模块对日志级别(例如,logging.DEBUG
,logging.INFO
,等等)使用这种解决方案。是的---这里重要的是拼写检查和指定允许的值,可能不是性能。是的---这里重要的是拼写检查和指定允许的值,可能不是表演。