python中可选对象的实现

optional.p的Python项目详细描述


可选.py

Build StatusBuild StatusCoverage StatusLicensePython VersionsContributorsOpen Source LoveDownloads

python可选对象的实现

为什么

作为空的None和作为错误结果的None之间存在差异。一个常见的坏习惯是 返回None表示缺少某些内容。这样做会在代码中引入歧义。

例如:

thing=stuff.getSomeThing().getAnotherThing()

如果getsomething的结果返回None,会发生什么?我们会得到一个AttributeError: 'NoneType' object has no attribute 'getAnotherThing'

你能做些什么来防止这种例外?你可以防御性地写作:

something=stuff.getSomeThing()ifsomethingisnotNone:thing=something.getAnotherThing()

然而,如果我们加入到我们的链中,你可以想象防御性检查的嵌套是如何迅速累积起来的。这些防御检查混淆了我们的实际业务逻辑,降低了可读性。 此外,防御检查是一个容易出错的过程,因为很容易忘记检查所需的条件。

因此,我们提供一个可选的对象作为替代。

安装

与python 2和3都兼容!

$ pip install optional.py

用法

  1. 您可以使用:

    fromoptionalimportOptional
  2. 您可以将其设置为空:

    代替::尖叫猫:

    returnNone

    你可以:微笑猫:

    returnOptional.empty()

    returnOptional.of()
  3. 您可以将其设置为包含以下内容:

    代替::尖叫猫:

    return"thing"

    你可以:微笑猫:

    returnOptional.of("thing")
  4. 您可以检查它是否存在:

    代替::尖叫猫:

    ifthingisnotNone:

    你可以:微笑猫:

    thing=some_func_returning_an_optional()ifthing.is_present():

    或者::傻笑猫:

    thing=some_func_returning_an_optional()ifthing:
  5. 您可以检查它是否为空:

    代替::尖叫猫:

    ifthingisNone:

    你可以:微笑猫:

    thing=some_func_returning_an_optional()ifthing.is_empty():

    或者::傻笑猫:

    thing=some_func_returning_an_optional()ifnotthing:
  6. 您可以得到值:

    代替::尖叫猫:

    print(thing)

    你可以做::傻笑猫:

    thing=some_func_returning_an_optional()...print(thing.get())

    但这不是使用此库的推荐方法。

  7. 如果为空,则无法获取该值:

    而不是::哭猫脸:

    ifthingisNone:print(None)# very odd

    你可以做::傻笑猫:

    thing=some_func_returning_an_optional()ifthing.is_empty():print(thing.get())# **will raise an exception**

    但这将引发异常!

  8. 您可以获取默认值:

    而不是::哭猫脸:

    thing=some_func_may_return_none()ifthingisNone:thing='23'

    或::尖叫猫:

    thing=Optional.of(some_func_may_return_none())ifthing.is_empty():thing='23'else:thing=thing.get()

    你可以做::傻笑猫:

    thing=Optional.of(some_func_may_return_none()).get_or_default('23')
  9. 您可以让'u或'u raise在消失时引发任何异常:

    代替::尖叫猫:

    try:thing=some_func_returning_an_optional()returnthing.get()exceptOptionalAccessOfEmptyException:raiseMyCustomException()

    你可以做:心眼猫:

    returnsome_func_returning_an_optional().get_or_raise(MyCustomException())
  10. 最佳使用:您可以在状态下链接:

    代替::尖叫猫:

    ifthingisnotNone:print(thing)

    你可以做:心眼猫:

    thing=some_func_returning_an_optional()thing.if_present(lambdathing:print(thing))
  11. 最佳用法:您可以在不存在时链接:

    代替::尖叫猫:

    ifthingisnotNone:print(thing)else:print("PANTS!")

    你可以做:心眼猫:

    thing=some_func_returning_an_optional()thing.if_present(lambdathing:print(thing)).or_else(lambda_:print("PANTS!"))

    注意,这里的lambda可以换成实际的函数名。

  12. 最佳使用:您可以在不存在的情况下运行供应商:

    代替::尖叫猫:

    thing=some_func_returning_an_empty_optional()ifthing.is_empty():thing=Optional.of("pants")print(thing.get())# Prints "pants"

    你可以做:心眼猫:

    defsome_supplier():return"pants"thing=some_func_returning_an_empty_optional().or_else(some_supplier)print(thing.get())# Prints "pants"
  13. 最佳使用:您可以在不在场的情况下提出:

    代替::尖叫猫:

    ifthingisNone:raiseSomeException("Boom!")

    你可以做:心眼猫:

    thing=some_func_returning_an_optional()thing.if_present(lambdathing:print(thing)).or_else_raise(SomeException("Boom!"))
  14. 最佳用法:您可以映射函数::心眼猫:

    defmapping_func(thing):returnthing+"PANTS"thing_to_map=Optional.of("thing")mapped_thing=thing_to_map.map(mapping_func)# returns Optional.of("thingPANTS")

    注意如果映射函数返回None,那么映射调用将返回Optional.empty()。阿尔索 如果对空的可选项调用map,它将返回Optional.empty()

  15. 最佳用法:您可以展开映射一个函数,该函数已返回一个可选的::心眼猫:

    defflat_mapping_func(thing):returnOptional.of(thing+"PANTS")thing_to_map=Optional.of("thing")mapped_thing=thing_to_map.map(mapping_func)# returns Optional.of("thingPANTS")

    注意这不会返回可选的。使用此用于返回选项的映射函数。 如果与此一起使用的映射函数不返回可选值,则调用flat_map将引发 FlatMapFunctionDoesNotReturnOptionalException

  16. 您可以比较两个选项::smile_cat:

    Optional.empty()==Optional.empty()# TrueOptional.of("thing")==Optional.of("thing")# TrueOptional.of("thing")==Optional.empty()# FalseOptional.of("thing")==Optional.of("PANTS")# False

测试

有完整的测试覆盖率,它们在python 2和3中都通过了测试。

运行单元测试

首先,使用:

test_requirements.txt中安装需求
$ pip install -r test_requirements.txt

您可以使用:

$ pytest

测试覆盖率

您可以使用:

$ pytest --cov=optional test/
$ coverage report

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
rest如何在java中访问摘要身份验证   Java如何获取类和jar文件的Java代码   java查找给定数字中的十进制数   类Lcom/google/firebase/FirebaseApp中没有虚拟方法zzbzo()Z;或者它的超类   javahibernate二级缓存&JUnit   java如何自动添加XMLAnnotations   使用java在google drive中获取上传的文件名?   Java使用GLFW复制可转移图像   java Android Intent不会发送值   使用Objectify在Google CloudDatastore中使用java findRecord   照片编辑器中的java pointerIndex超出范围异常   java使用Spring Boot/JPA生成唯一字段的正确方法是什么?   安卓无法在firebase上上载图像,因为拒绝了之前失败的java类上的reinit。类错误   java如何在thymeleaf中构建绝对URL?   从Linux到2012r2 Active Directory的LDAPS Java查询的最低要求是什么   泛型Java接口反射   带地址字段的java Google地图标记   关于即将推出的forkjoin框架的java资源   jsp中的BEAN法则