Python function that accepts file object or path

前端 未结 2 1796
南笙
南笙 2020-12-30 05:23

I want to write a function that accepts either a path as a string or a file object. So far I have:

def awesome_parse(path_or_file):
    if isinstance(path_or         


        
相关标签:
2条回答
  • 2020-12-30 05:46

    The odd thing about your code is that if it is passed an open file, it will close it. This isn't good. Whatever code opened the file should be responsible for closing it. This makes the function a bit more complex though:

    def awesome_parse(path_or_file):
        if isinstance(path_or_file, basestring):
            f = file_to_close = open(path_or_file, 'rb')
        else:
            f = path_or_file
            file_to_close = None
        try:
            return do_stuff(f)
        finally:
            if file_to_close:
                file_to_close.close()
    

    You can abstract this away by writing your own context manager:

    @contextlib.contextmanager
    def awesome_open(path_or_file):
        if isinstance(path_or_file, basestring):
            f = file_to_close = open(path_or_file, 'rb')
        else:
            f = path_or_file
            file_to_close = None
    
        try:
            yield f
        finally:
            if file_to_close:
                file_to_close.close()
    
    def awesome_parse(path_or_file):
        with awesome_open(path_or_file) as f:
            return do_stuff(f)
    
    0 讨论(0)
  • 2020-12-30 06:11

    You could do:

    def awesome_parse(do_stuff):
        """Decorator to open a filename passed to a function
           that requires an open file object"""
        def parse_path_or_file(path_or_file):
            """Use a ternary expression to either open the file from the filename
               or just pass the extant file object on through"""
            with (open(path_or_file, 'rb') 
                   if isinstance(path_or_file, basestring) 
                    else path_or_file) as f:
                return do_stuff(f)
        return parse_path_or_file
    

    And then when you declare any function that does stuff on an open file object:

    @awesome_parse
    def do_things(open_file_object):
        """This will always get an open file object even if passed a string"""
        pass
    
    @awesome_parse
    def do_stuff(open_file_object):
        """So will this"""
        pass
    

    Edit 2: More detailed info on the decorator.

    0 讨论(0)
提交回复
热议问题