没有“最好”的方法,因为你不只是检查一个属性是否存在;它总是一些大型计划的一部分.有几种正确的方法和一种值得注意的错误方法.
错误的方法
if 'property' in a.__dict__:
a.property
这是一个演示,显示此技术失败:
python getattr,class A(object):
@property
def prop(self):
return 3
a = A()
print "'prop' in a.__dict__ =", 'prop' in a.__dict__
python 进程?print "hasattr(a, 'prop') =", hasattr(a, 'prop')
print "a.prop =", a.prop
输出:
'prop' in a.__dict__ = False
hasattr(a, 'prop') = True
a.prop = 3
python 排序?大多数时候,你不想乱用__dict__.它是做特殊事物的特殊属性,检查属性是否存在是相当平凡的.
EAFP的方式
Python中常见的习语是“更容易请求宽恕而不是许可”,简称EAFP.您将看到许多使用此习惯用法的Python代码,而不仅仅是用于检查属性是否存在.
# Cached attribute
try:
big_object = self.big_object
enumerate python。# or getattr(self, 'big_object')
except AttributeError:
# Creating the Big Object takes five days
# and three hundred pounds of over-ripe melons.
big_object = CreateBigObject()
self.big_object = big_object
python元祖。big_object.do_something()
请注意,这与打开可能不存在的文件完全相同.
try:
f = open('some_file', 'r')
except IOError as ex:
if ex.errno != errno.ENOENT:
python中readlines?raise
# it doesn't exist
else:
# it does and it's open
此外,用于将字符串转换为整数.
try:
python编程、i = int(s)
except ValueError:
print "Not an integer! Please try again."
sys.exit(1)
甚至导入可选模块……
try:
python 输入、import readline
except ImportError:
pass
LBYL的方式
当然,hasattr方法也有效.这种技术被称为“在你跳跃之前看”,或简称为LBYL.
# Cached attribute
python for?if not hasattr(self, 'big_object'):
big_object = CreateBigObject()
self.big_object = CreateBigObject()
big_object.do_something()
(hasattr内置实际上在3.2之前的Python版本中就异常而言表现得很奇怪 – 它会捕获它不应该的异常 – 但这可能是无关紧要的,因为这样的异常是不可能的.hasattr技术也比尝试慢/ except,但你不经常调用它,并且差异不是很大.最后,hasattr不是原子的,所以如果另一个线程删除属性它可能抛出AttributeError,但这是一个牵强附会的场景无论如何你都需要非常小心线程.我不认为这三个差异中的任何一个值得担心.)
使用hasattr比try / except简单得多,只要你需要知道的是属性是否存在.对我来说最大的问题是LBYL技术看起来“奇怪”,因为作为Python程序员,我更习惯于阅读EAFP技术.如果您重写上面的示例以便它们使用LBYL样式,则会得到笨拙,完全不正确或难以编写的代码.
python查看类的属性和方法、# Seems rather fragile...
if re.match('^(:?0|-?[1-9][0-9]*)$', s):
i = int(s)
else:
print "Not an integer! Please try again."
sys.exit(1)
python判断一个变量属于哪个类型,而LBYL有时是完全错误的:
if os.path.isfile('some_file'):
# At this point, some other program could
# delete some_file...
f = open('some_file', 'r')
如果你想编写一个用于导入可选模块的LBYL函数,请成为我的客人…听起来这个函数将是一个完整的怪物.
Python类的属性、getattr方式
如果您只需要一个默认值,getattr是try / except的较短版本.
x = getattr(self, 'x', default_value)
如果构造的默认值很昂贵,那么你最终会得到这样的结果:
x = getattr(self, 'attr', None)
if x is None:
怎么检查python代码错误、x = CreateDefaultValue()
self.attr = x
或者如果None是可能的值,
sentinel = object()
x = getattr(self, 'attr', sentinel)
if x is sentinel:
python为什么叫爬虫,x = CreateDefaultValue()
self.attr = x
结论
在内部,getattr和hasattr builtins只使用try / except技术(除了用C语言编写).因此,它们的行为方式与它的重要性相同,而选择正确的方式则取决于环境和风格.
try / except EAFP代码总是会以错误的方式使一些程序员感到厌烦,而hasattr / getattr LBYL代码会让其他程序员感到烦恼.它们都是正确的,并且通常没有真正令人信服的理由选择其中一个. (然而其他程序员感到厌恶的是你认为属性未定义是正常的,而且一些程序员感到震惊,甚至可能在Python中有一个未定义的属性.)
版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。
工作时间:8:00-18:00
客服电话
电子邮件
admin@qq.com
扫码二维码
获取最新动态