我有一个函数,其中有时一个参数可以为none,我想将其与另一个对象进行比较。但是,如果我尝试调用对象属性,即使两个对象都不是,脚本也会在None上引发异常(请参见下面的示例)。
def do_animals_make_same_sound(first_animal, second_animal):
if first_animal.sound = second_animal.sound:
print('Yes they do!')
但是如果两个动物都不是,则当我希望它打印时会抛出异常('是的,他们这样做!'),但是看来我必须写一个非常难看的If语句:
def do_animals_make_same_sound(first_animal, second_animal):
if (first_animal is None and second_animal is None) or (first_animal is not None and first_animal.sound == second_animal.sound):
print('Yes they do!')
有更好的方法吗?
答案 0 :(得分:2)
以下代码更清晰,恕我直言:
def do_animals_make_same_sound(first_animal, second_animal):
# early return if one of the two animals is missing, ensure both exist
if not (first_animal and second_animal):
return
if first_animal.sound == second_animal.sound:
print('Yes they do!')
答案 1 :(得分:0)
这不是很好,但是一种方法可以是使用带有默认值的getattr
,因此None
(以及没有所需属性的任何其他内容)的行为就好像它具有默认值作为其值属性。例如:
if first_animal.sound == second_animal.sound:
可以成为:
if getattr(first_animal, 'sound', None) == getattr(second_animal, 'sound', None):
我实际上不建议这样做,因为它会默默地忽略错误。在实际代码中,我几乎总是让AttributeError
传播;在任何合理的情况下,我都不认为None
是“某物”的可接受替代,其中“某物”具有特定的行为或属性;如果调用方正在传递None
,则几乎可以肯定是一个错误,不应将其忽略。
答案 2 :(得分:0)
我认为,如果对象之一为“无”,那么您首先必须了解什么意思。基本上有三种情况:
一个或两个对象都不是
一个或两个对象没有sound
属性
都具有sound
属性
对于#1,我假设它应该抛出错误,因为实际上没有比较。如果两个对象均为“无”,则代码将打印“是”。
对于#2,您可以使用ShadowRanger的建议,如果两个对象都具有None
作为sound
属性,并且您认为这是正常行为,请使用ShadowRanger的解决方案。
对于#3,只需进行常规比较
def do_animals_make_same_sound(first_animal, second_animal):
if not first_animal or not second_animal:
print("One of the objects is None")
elif getattr(first_animal, 'sound', None) == getattr(second_animal, 'sound', None):
print("Yes, they do!")
答案 3 :(得分:0)
如果这是足够通用的模式,我将使用装饰器来专门捕获None案例并对其进行处理。这使逻辑脱离了功能。但是您需要确切地定义None在这里的含义...您可以为两者都通过None,这有点奇怪,但是仅为其中一个通过None是不合法的。无论如何,装饰器都是一种以简洁的方式抽象出一些常见逻辑的好方法。
def NoNone(f):
@functools.wraps(f)
def _no_none_func(*args, **kwargs):
if args[0] == None and args[1] == None:
print('Both are None')
return
return f(*args)
return _no_none_func
@NoNone
def do_animals_make_same_sound(first_animal, second_animal):
if first_animal.sound == second_animal.sound:
print('Yes they do!')
else:
print("No they don't!")