3

I want to write a function named size() which will accept either a file name or a list of filenames and return the size of the file or sum of its sizes respectively. How to do this without function overloading which is not available in python?

thanks

suresh

10
  • @eyquem Users should be encouraged to use proper English grammar and spelling, but your attitude is rather confrontational. Don't bash the new users, just tell them what is expected of them. Commented Aug 28, 2011 at 11:28
  • @Paul, thanks for the support. I am a new user here. I completely understand that proper English grammar and spelling must be used. But if the questions would be subject to hair splitting analysis of the language constructs, I am afraid, it would deter many.... Commented Aug 28, 2011 at 20:13
  • @suresh Well, thank you to keep so kind. I appreciate people that are able to admit their little faults. Hence I can appreciate myself, because I do a lot of faults. - I will delete all my comments, you will be as white as snow again :-) to begin on stackoverflow. If you correct their with its, I even will upvote your question ! Commented Aug 28, 2011 at 21:56
  • @eyquem With my English knowledge, I could not see if its is better. That's why I did not change it earlier. But I guess its is more precise. To err is human right? But our endeavor should be to reduce it as much as we can....(As learned from other masters) Commented Aug 28, 2011 at 22:25
  • @suresh I was thinking to "will accept either a file name or a list of filenames, and return its size or the sum of their sizes respectively" But I won't go on playing as if I was a master of English Commented Aug 28, 2011 at 22:40

4 Answers 4

5
def size(*files):
    for file in files:
        print file

*files is a special argument type which will catch all arguments into a list. Thus, if you call size like this:

size("file1.txt", "file2.xml")

files will be a list containing file1.txt and file2.xml. If you call it with only one argument, it will still be placed in a list.

To call the function with a list of files, use the same operator, but use in when you call the function:

file_list = ["file1.txt", "file2.xml"]
size(*file_list)
Sign up to request clarification or add additional context in comments.

9 Comments

This is not correct. The OP wishes to send either a string or a list of strings. Your code assumes multiple args...
@gahooa, this method allows you to send both a single argument, and a list of arguments. What is your point?
Maybe I'm taking the term list too literally, but as I read the original post, it says he wants either size(string_with_filename) or size(list_of_filenames). A poor design choice.
Just to be clear, the code presented in this answer is a good design and I recommend that @suresh just use it.
In this method, I will have to prefix a * to the argument if it is a list right? But then I do not know if the input is going to be a list or not apriori. So I guess this will not work.
|
3

I recommend using overloading internally as it is most intuitive to a user of the function

import os

def file_size(files):

    if isinstance(files, str):
        files = [files] # enlist

    size = 0
    for f in files:
        size += os.path.getsize(f)

    return size


if __name__ == '__main__':
    print file_size(__file__)
    print file_size([__file__, __file__])
    print file_size([])

3 Comments

Wont I be unnecessarily holding all the size values in the list sizes and hence wasting memory, while I only need their sum of sizes? I am not sure whether my thinking is right or not as I am new to Python....
I see "sum of sizes" - i didn't understand the question due to the typo. Yes instead of keeping all sizes, it is possible to just keep the sum. In this case, the batch_call variable is not useful because the type of the output doesn't change if the input is a string or a list
@selvin " i didn't understand the question due to the typo" . Nor did I. Which is the reason I couldn't answer.
1

I believe this is what you asked for. However, I think it's a poor design choice. Remember the zen of python...

In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.

In concept, just check the input argument for what type it is

def size(arg):
    if isinstance(arg, str):
        retval = ... #get size of arg
        return retval
    else:
        retval = []
        for f in arg:
           retval.append(...)  #get size of each file
        return retval

Comments

1
def size(files):
    # convert to a list if only one item given
    if not hasattr(files,'__iter__'):
        files = [ files ]

    for fname in files:
        ...do something with fname...

EDIT: this variant has the advantage that you can add more parameters (e.g. min_mtime) to this function in the future

2 Comments

@Holzner, I just now discovered that hasattr('any_string','__iter__') is True. So one need to use isinstance or something like that....
in fact I realized that it returns True in python 3 but False in python 2.6 ...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.