Using try-catch to handle multiple possible file types?

Neil Cerutti mr.cerutti at gmail.com
Wed Nov 20 16:05:03 CET 2013


Steven D'Aprano steve+comp.lang.python at pearwood.info via python.org
8:56 PM (12 hours ago) wrote:
> Write a helper function:
>
> def process(opener):
>     with opener('blah.txt', 'rb') as f:
>         for line in f:
>             print(line)

As another option, you can enter the context manager after you decide.

try:
    f = gzip.open('blah.txt', 'rb')
except IOError:
    f = open('blah.txt', 'rb')
with f:
   # processing
   for line in f:
       print(line)

contextlib.ExitStack was designed to handle cases where entering
context is optional, and so also works for this use case.

with contextlib.ExitStack() as stack:
    try:
        f = gzip.open('blah.txt', 'rb')
    except IOError:
        f = open('blah.txt', 'rb')
    stack.enter_context(f)
    for line in f:
       print(line)

-- 
Neil Cerutti

On Tue, Nov 19, 2013 at 8:56 PM, Steven D'Aprano
<steve+comp.lang.python at pearwood.info> wrote:
> On Tue, 19 Nov 2013 16:30:46 -0800, Victor Hooi wrote:
>
>> Hi,
>>
>> Is either approach (try-excepts, or using libmagic) considered more
>> idiomatic? What would you guys prefer yourselves?
>
> Specifically in the case of file types, I consider it better to use
> libmagic. But as a general technique, using try...except is a reasonable
> approach in many situations.
>
>
>> Also, is it possible to use either approach with a context manager
>> ("with"), without duplicating lots of code?
>>
>> For example:
>>
>> try:
>>       with gzip.open('blah.txt', 'rb') as f:
>>               for line in f:
>>                       print(line)
>> except IOError as e:
>>       with open('blah.txt', 'rb') as f:
>>               for line in f:
>>                       print(line)
>>
>> I'm not sure of how to do this without needing to duplicating the
>> processing lines (everything inside the with)?
>
> Write a helper function:
>
> def process(opener):
>     with opener('blah.txt', 'rb') as f:
>         for line in f:
>             print(line)
>
>
> try:
>     process(gzip.open)
> except IOError:
>     process(open)
>
>
> If you have many different things to try:
>
>
> for opener in [gzip.open, open, ...]:
>     try:
>         process(opener)
>     except IOError:
>         continue
>     else:
>         break
>
>
>
> [...]
>> Also, on another note, python-magic will return a string as a result,
>> e.g.:
>>
>> gzip compressed data, was "blah.txt", from Unix, last modified: Wed Nov
>> 20 10:48:35 2013
>>
>> I suppose it's enough to just do a?
>>
>>     if "gzip compressed data" in results:
>>
>> or is there a better way?
>
> *shrug*
>
> Read the docs of python-magic. Do they offer a programmable API? If not,
> that kinda sucks.
>
>
>
> --
> Steven
> --
> https://mail.python.org/mailman/listinfo/python-list



-- 
Neil Cerutti <mr.cerutti+python at gmail.com>



More information about the Python-list mailing list