首页 > 解决方案 > "with suppress" not working anymore in my Python 3 code?

问题描述

I'm processing the following XML from an API, which has a set of records like these:

<br.com.wine.sfweb.rest.controller.api.products.ProductDTO>
   <sku>18683</sku>
   <imageUrl>/renderImage.image?imageName=produtos/18683-01.png</imageUrl>
   <id>89117</id>
   <name>WineBox W Explorer Series</name>
   <type>Vinho</type>
   <attributes>
      <marketingCampaign>estoque-limitado</marketingCampaign>
      <country>Wine</country>
   </attributes>
   <ratings>
      <averageRating>4.19</averageRating>
      <numberOfRatings>21</numberOfRatings>
      <histogram>
         <entry>
            <string>3.0</string>
            <long>2</long>
         </entry>
         <entry>
            <string>4.0</string>
            <long>9</long>
         </entry>
         <entry>
            <string>1.0</string>
            <long>1</long>
         </entry>
         <entry>
            <string>5.0</string>
            <long>9</long>
         </entry>
      </histogram>
   </ratings>
   <rating>4.19</rating>
   <numberOfRatings>21</numberOfRatings>
   <available>true</available>
   <listPrice>402.00</listPrice>
   <salesPriceNonMember>402.00</salesPriceNonMember>
   <salesPriceClubMember>341.70</salesPriceClubMember>
</br.com.wine.sfweb.rest.controller.api.products.ProductDTO>

I do know that the children <attributes> is not always full, as per the documentation it is not required.

I've been processing all these records successfully (even the ones that are not there) by using, for example:

from contextlib import suppress

with suppress(AttributeError): tipoVinho = produtos.find('attributes/type').text
with suppress(AttributeError): paisVinho = produtos.find('attributes/country').text

So that if <attributes><type> is not there it just skips the Attribute error and moves on.

Now, out of the blue, whenever I fall into a missing attribute, I'm getting a "name 'tipoVinho' is not defined" error, like if the with suppress clause wasn't doing anything anymore.

I haven't upgraded anything, it just started to days ago (note that I had several cases where some attributes are missing, so this is pretty common).

Am I missing anything?

标签: pythonxml

解决方案


When you are suppressing the AttributeError, the assignment is cancelled. After all, the right-hand-side expression (produtos.find().text) did not return, at all. It did not even return None! Instead, it threw an Exception. This leads to cases where tipoVinho is undefined.

You will need to do special-casing for when the exception occurs, making contextlib.suppress not the right tool. Instead, just use exceptions:

try:
    tipoVinho = produtos.find('attributes/type').text
except AttributeError:
    tipVinho = None

Or set tipVinho to some default value before your possibly-failing assignment. Make sure to reset it in each loop iteration, if you do that!


推荐阅读