Python 3
数据可能是字符串,字节或EmailMessage。
这是从数据中获取字节数的最有效方法吗?
while True:
try:
# data is a string
f.write(data.encode('utf-8'))
break
except:
pass
try:
# data is an EmailMessage
f.write(data.get_bytes())
break
except:
pass
try:
# data is bytes
f.write(data)
break
except:
pass
else:
self.log.info('Exiting, unknown attachment type')
sys.exit(1)
答案 0 :(得分:7)
if hasattr(data, "encode"):
f.write(data.encode('utf-8'))
elif hasattr(data, "get_bytes"):
f.write(data.get_bytes())
else:
try:
f.write(data)
except TypeError:
self.log.info('Exiting, unknown attachment type')
sys.exit(1)
修改强>
这就像鸭子一样 - “如果它像鸭子一样嘎嘎叫,它就是一只鸭子;如果它编码,它就是一个字符串”。
这比if isinstance(data, str)
优先,因为限制较少;只要一个对象知道如何将自己编码为字节,我们并不关心它是否实际上是一个字符串。
异常相对较慢,应保留用于处理意外或不太可能的错误。
答案 1 :(得分:1)
来自维基百科:
例如,在非鸭类型语言中,可以创建一个函数 这要求传递给它的对象按顺序为Duck类型 确保该功能可以使用对象的步行和嘎嘎声 方法。在鸭子类型的语言中,该函数将采用一个对象 任何类型的,只需调用其walk和quack方法,生成一个 如果未定义运行时错误。鸭子打字实践不是正式指定类型,而是依赖于文档,清晰的代码和测试以确保正确使用。
这并不意味着你可以调用你想要的任何方法,如果它不存在则会发现异常。你仍然需要努力只调用你确定会在那里的方法。鸭子打字与你不关心对象的类型(如果你把它传递给一个函数,你没有像在Java中那样指定类型)这一事实更相关,但是仍然确定它会响应特定的方法调用。
在您的情况下,我要做的是使用公共方法get_data
围绕每个对象(String,EmailMessage,bytes)创建一个包装器,其中get_data的每个实现都特定于对象的类型它包裹着(encode
,get_bytes
等。然后你的循环看起来如下:
while True:
try:
# data is a string
f.write(data.get_data())
break
except:
pass
修改:您可能还希望看到与您的问题相关的问题:How to handle "duck typing" in Python?