Search code examples
pythonpython-2.7unzip

Extract a particular file doesn't works in python


I need to 1) Find a zipfile at a particular directory location 2) If it exists then unzip it 3) Out of its contents find a specific file and move it to other directory.

def searchfile():
    for file in os.listdir('/user/adam/datafiles'):
        if fnmatch.fnmatch(file, 'abc.zip'):
            return True
     return False

if searchfile():
    print('File exists')
else:
    print('File not found')

def file_extract():    
    os.chdir('/user/adam/datafiles')
    file_name = 'abc.zip'
    destn = '/user/adam/extracted_files'
    zip_archive = ZipFile (file_name)
    zip_archive.extract('class.xlsx',destn)
    print("Extracted the file")
    zip_archive.close()

file_extract()

When I execute the above script, it shows no compile time issues or runtime issues,. but it just works for the first function. When I check for the files in the extracte_files folder I don't see the files.


Solution

  • So for the sake of completeness and as my comment solved your issue, I guess I should make it an Answer:

    In Python, if a function foo is defined (def foo(<...>):),

    • foo refers to the function itself and can be copied around (effectively copying a pointer), passed to other functions, ... as about any object;
    • foo() is a call without passed argument to that function.

    As this question does not seem to be an assignment, I will add the following:

    To improve your code, you might want to look into:

    • Parameters to functions (you functions are currently only doing one single thing. For example, you could pass the file and directory names to searchfile);
    • os.path and all its content;
    • The in test for checking if an object is in a container;
    • The with statement for clearer and safer handling of objects such as ZipFile instances;
    • The x if b else y construst; Notice that even if the archive does not exist, your code still attempts to extract a file from it.

    Here is a more robust way to implement what you want:

    import os
    import zipfile
    
    arch_name, file_name = 'abc.zip', 'class.xlsx'
    home_dir = os.path.join(os.path.abspath(os.sep), 'user', 'adam')
    # or even better: home_dir = os.path.expanduser('~')
    arch_dir = os.path.join(home_dir, 'datafiles')
    dest_dir = os.path.join(home_dir, 'extracted_files')
    
    arch_path = os.path.join(arch_dir, arch_name)
    
    if os.path.isfile(arch_path):
        print('File {} exists'.format(arch_path))
        with zipfile.ZipFile(arch_path) as archive:
            archive.extract(file_name, dest_dir)
        print('Extracted {} from {}'.format(file_name, arch_name))
    else:
        print('File {} not found'.format(arch_path))
    

    Disclaimer: This code is untested and could contain minor mistakes!

    Notice how the second half of the code works with generic variables that can easily be modified in a single place in the first half. Also, notice the improved readability of if os.path.isfile(arch_path): as opposed to if searchfile(): (requiring us to then read the implementation of searchfile).