python .get()和None

时间:2015-12-18 14:08:58

标签: python

我喜欢python one liners:

u = payload.get("actor", {}).get("username", "")

我面临的问题是,我无法控制有效负载'包含,除了知道它是一本字典。所以,如果'有效载荷'没有"演员",或者它确实和演员没有"用户名",这个单行是没问题的。

当有效载荷有演员时会出现问题,但演员不是字典。

作为一个单一的班轮,是否可以作为一种全面的方式来实现这一点,并考虑“演员”的可能性。可能不是字典?

当然,我可以使用' isinstance'来查看类型,但这并不是很好。

我本身并不需要一个班轮,只是要求最有效的方法来确保“你好”。毫无例外地填充,并且事先不知道有效负载是什么。

3 个答案:

答案 0 :(得分:9)

使用EAFP

正如xnx建议的那样,你可以利用以下python范例:

  

Easier to ask for forgiveness than permission

你也可以在KeyError上使用它:

try:
    u = payload["actor"]["username"]
except (AttributeError, KeyError):
    u = ""

使用带有宽松索引的包装器

有时在Python中使用类似空条件运算符的东西会很好。使用一些辅助类,可以将其压缩为单行表达式:

class Forgive:
  def __init__(self, value = None):
    self.value = value
  def __getitem__(self, name):
    if self.value is None:
      return Forgive()
    try:
      return Forgive(self.value.__getitem__(name))
    except (KeyError, AttributeError):
      return Forgive()
  def get(self, default = None):
    return default if self.value is None else self.value

data = {'actor':{'username': 'Joe'}}
print(Forgive(data)['actor']['username'].get('default1'))
print(Forgive(data)['actor']['address'].get('default2'))

ps:除了__getattr__之外,还可以重新定义__getitem__,所以你甚至可以写Forgive(data)['actor'].username.get('default1')

答案 1 :(得分:4)

为什么不使用例外:

try:
    u = payload.get("actor", {}).get("username", "")
except AttributeError:
    u = ""

答案 2 :(得分:-1)

如果你真的需要在一行中完成,你必须自己实现这个功能。如果你在程序中多次使用这种语义,这是值得做的。

有两种方法可以实现:payload的函数或自定义类字典对象。

1)函数处理actor不是dict的情况。它可以检查isinstance或执行try或其他任何内容 - 它不是必需的。用法看起来像u = get("username", "", payload.get("actor", {}))u = get("", payload, 'actor', 'username')(对payload中的项目进行任意数量的嵌套调用)。

2)一类自定义对象是一个强大的东西 - 如果你能在程序中真正需要这种抽象,那就去做吧。 dictUserDict(在Python3中)的后代可以检查__getitem__次调用中存储或输出的内容。

相关问题