最优雅的python方式在使用它们时处理空/缺失/未初始化的对象/属性

时间:2017-08-24 12:02:16

标签: python error-handling

if form.admirer_or_model == "model":
    model_form_css_style = None

表单可能为无,表单中可能不存在 admirer_or_model

处理这种情况最优雅的方法是什么?

2 个答案:

答案 0 :(得分:2)

有多种可能的选择。哪个是最方便的,一般取决于错误发生时你的代码流应该改变多少。

  • 如果流量完全消失 - 即功能刚刚破裂

    • 不做任何事情,在两种情况下都会提出AttributeError

      if form.admirer_or_model == "model":  # will raise AttributeError in both cases
                                            #'cuz None has no such attribute, either
          <...>
      
  • 如果流量发生剧烈变化 - 即之后有一些短暂的错误处理代码退出该功能

    • 处理AttributeError - 特别是如果要同时处理这两种情况:

      try: if form.admirer_or_model == "model":
          <...>
      except AttributeError as e:
          <handle the error and quit, e.g.>
          raise TypeError("`form': " + e.message)    # a common way to signal that
                                                     #an argument failed a type and/or
                                                     #a duck test
      
    • 按照下一个建议检查,但没有else子句:

      if form is None or not hasattr(form,'admirer_or_model'):
          <handle the error and quit>
      <continue normally>
      
  • 如果流量发生变化,但功能仍然有效 - 即您为&#34;正常&#34;提供了替代代码块。一个然后进一步的

    • 检查if(form)if(form is (not) None)(如果有效form可评估为False)和hasattr(form,'admirer_or_model'),则else条款包含替代块:

      if form and hasattr(form,'admirer_or_model'):
          <normal case>
      else:
          <alternate case>
      <proceed further>
      
    • 处理错误但不要退出 - 特别是如果两种错误的处理都很常见:

      try: if form.admirer_or_model == "model":
          <processing on no error and the condition true>
      except AttributeError as e:
          <processing only on error>
      <continue normally>
      
  • 如果流量根本没有变化,即您只提供默认值

    • 使用三元/其他默认提供构造 - 例如form if form else <default>getattr(form,'admirer_or_model',<default>)

      if getattr(
              (form if form else <default>),
              'admirer_or_model',<default>) == "model":
          <...>
      

另请注意,其中一些构造将错误处理块放在if块之前,而== "model"块放在if之后。如果public static void testSend() throws UnknownHostException, IOException{ Socket socket = null; OutputStreamWriter osw; String str = "Hello World\n"; socket = new Socket("localhost", 4308); osw = new OutputStreamWriter(socket.getOutputStream(), "UTF-8"); osw.write(str, 0, str.length()); osw.flush(); socket.close(); } 块很大,这可能会影响可读性:错误处理块最好放在触发错误的行附近。

答案 1 :(得分:0)

您可以使用getattr,默认传递sentinel值:

    Firebase.CrashReporting.CrashReporting.Log("blah");

上述内容将在Python实现safe navigation之前完成。