reo*_*eox 6 python syntactic-sugar
假设你有一个可以返回某个对象的函数或者没有:
def foobar(arg):
if arg == 'foo':
return None
else:
return 'bar'
Run Code Online (Sandbox Code Playgroud)
现在你调用这个方法,你想对对象做一些事情,对于这个例子,我得到一个str,所以我可能想调用该upper()函数.现在有两种情况可能发生,第二种情况会失败,因为None没有方法upper()
foobar('sdfsdgf').upper()
foobar('foo').upper()
Run Code Online (Sandbox Code Playgroud)
当然这很容易解决:
tmp = foobar('foo')
if tmp is not None:
tmp.upper()
# or
try:
foobar('foo').upper()
except ArgumentError:
pass
# or
caller = lambda x: x.upper() if type(x) is str else None
caller(foobar('foo'))
Run Code Online (Sandbox Code Playgroud)
但是异常处理可能不够具体,我可能会发现一个可能很重要的异常(=调试变得更难),而第一种方法很好但可以产生更大的代码而第三种选择看起来很不错但是你必须为所有可能的功能做到这一点,所以方法一可能是最好的.
我想知道是否有任何语法糖可以很好地处理这个问题?
Mar*_*ers 14
您可以使用:
(foobar('foo') or '').upper()
Run Code Online (Sandbox Code Playgroud)
括号内的表达式返回一个字符串,即使foobar()返回一个falsy值.
这确实导致None被空字符串替换.如果您的代码依赖于None保留,您最好的选择仍然是使用单独的if语句.upper()仅在返回值不调用时才调用None.
由于这个问题得到了回答,因此有一些新的发展使这种模式更容易一些.
该pymaybe包可以让你简单地包裹自己的价值观maybe来传播默默None值:
from pymaybe import maybe
maybe(foobar('foo')).upper()
Run Code Online (Sandbox Code Playgroud)
这与Martijn Pieters的答案非常相似,只是它保留了None值而不是用空字符串替换它们,并且在存在多个falsey值时它会更强大.
此外,看起来PEP 505上有一个标准跟踪草案提案,它希望添加类似于C#?.语言本身访问器的语法.我不确定它有多少支持,但它是一个寻找可能进一步增强的地方.