Search code examples
pythonargparse

What is type=argparse.FileType('rb') in Python


I am looking at other person's Python code:

import argparse
parser = argparse.ArgumentParser(description="Recover files from an NTFS volume")
parser.add_argument('--mft', type=argparse.FileType('rb'), help='Use given file as MFT')

and find this type argument a bit strange for a classic C++/Delphi/C# developer.

I can imagine what type=int is, but type=argparse.FileType('rb') ... ?!

I can suppose that it is a kind of "all in one" operation that takes a string argument and instantly uses it as a file name for opening a file for reading and returns its file variable (descriptor). Am I right?

The documentation doesn't reveal the mechanisms.


Solution

  • int and FileType work the same, although it may not be obvious at first. The type= parameter is just a callable used to create the object assigned to the parameter. argparse takes the original string parameter and, if type is not None, calls whatever object is there to create the value assigned to the parameter.

    If you use type=int, then int() is called. But you can use any callable - argparse doesn't care - it just calls whatever you supply. You could use type=open and then argparse would call open() and you'd get a character mode file opened read-only.

    You can use the __call__ magic method in your own classes to make callable class instances. That's what happens here. argparse.FileType creates an object that records file open parameters. When called with a single string via the __call__ method, it will open and return a file with those parameters. It's like open but lets you control the parameters.

    >>> import argparse
    >>> import os
    >>> os.path.exists("deleteme")
    False
    >>> file_type = argparse.FileType("wb")
    >>> file = file_type("deleteme")
    >>> file
    <_io.BufferedWriter name='deleteme'>
    >>> os.path.exists("deleteme")
    True