Suppose I have the following methods:
def read(file: str) -> List[str]:
temp = []
with open(file) as f_obj:
for line in f_obj:
temp.append(line)
return temp
def append_items_to_list(folders : List[str], file: str):
with open(file) as f_obj:
for line in f_obj:
folders.append(line)
def main():
source: str = "source.txt"
directories : List[str] = read(file=source)
print(len(directories))
folderList : List[str] = []
append_items_to_list(folders=folderList, file=source)
print(len(folderList))
if __name__ == '__main__':
main()
Both methods read from a file, and appends items to a List
. The first method creates a temporary List
and returns it, while the second accepts a List
as a parameter, and appends to it.
Is there a guideline that states which one is preferable? Are there any underlying problems I don't see that I should be concerned about with either one?
I guess you would have to look at why you need to construct a new List
, in this case, I don't need to construct a new List
, I can just use the second method.
Clarification:
It seems the general answer is to return a new List
, but I've narrowed down my problem a little more.
def do_work(source: Path, destination: Path):
# do some work with the folders.
def create_list_of_empty_folders(folders : List[str], folder: Path):
# Check if folder is empty, if so, append it to the List.
def cleanup(folders_to_remove: List[Path]):
# Remove all folders in the List from the HD.
def main():
portableHD = Path("Path\\to\\HD")
USB = Path("Path\\to\\USB")
empty_folders : List[Path] = []
for folder in portableHD.iterdir():
do_work(source=folder, destination=USB)
create_list_of_empty_folders(folders=empty_folders, folder=folder)
# Outside of the for loop we can safely remove the empty folders.
cleanup(folders_to_remove=empty_folders)
if __name__ == '__main__':
main()
In this context, I have no choice but to pass a List
and a folder
to my function. Obviously, I could write out the code in the for loop without the use of a function, but let's assume I want to write clean maintainable code.
In my first example, I don't really need to use function, I can read and append the data to a List
directly in the main
method:
def main():
file: str = "source.txt"
folders : List[str] = []
with open(file) as f_obj:
for line in f_obj:
folders.append(line)
if __name__ == '__main__':
main()
But let's assume more work needs to be done with each of these folders, so I refactor my code and create smaller methods, why is returning a temporary List
from a function more desirable?
Does your function really have to know that the goal of the caller is to append ?
Why can't my function know the caller wants to append to a List
? After all I did break down the code into smaller functions, one of which appends to a List
. Even if I were to rename my method to append(folders : List[str], file: str)
, the function parameters indicate what I want to append.