#!/usr/bin/python3 # -*- coding: utf-8 -*- """ File I/O open(filename, mode) https://docs.python.org/3/library/functions.html#open file_object = open(file_name [, access_mode][, buffering]) Defaulted values are optional: open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None) file_name The file_name argument is a string value, the name of the file that you want to access. Name must be an absolute or relative path, including the filename. access_mode The access_mode determines the mode in which the file has to be opened, i.e., read, write, append, etc. This is an optional parameter and the default file access mode is read (r). 'r' open for reading (default) 'w' open for writing, truncating the file first 'x' open for exclusive creation, failing if the file already exists 'a' open for writing, appending to the end of the file if it exists 'b' binary mode 't' text mode (default) '+' open a disk file for updating (reading and writing) 'U' universal newlines mode (deprecated) More verbosely: r Opens a file for reading only. The file pointer is placed at the beginning of the file. This is the default mode. rb Opens a file for reading only in binary format. The file pointer is placed at the beginning of the file. r+ Opens a file for both reading and writing. The file pointer will be at the beginning of the file. rb+ Opens a file for both reading and writing in binary format. The file pointer will be at the beginning of the file. w Opens a file for writing only. Overwrites the file if the file exists. If the file does not exist, creates a new file for writing. wb Opens a file for writing only in binary format. Overwrites the file if the file exists. If the file does not exist, creates a new file for writing. w+ Opens a file for both writing and reading. Overwrites the existing file if the file exists. If the file does not exist, creates a new file for reading and writing. wb+ Opens a file for both writing and reading in binary format. Overwrites the existing file if the file exists. If the file does not exist, creates a new file for reading and writing. a Opens a file for appending. The file pointer is at the end of the file if the file exists. That is, the file is in the append mode. If the file does not exist, it creates a new file for writing. ab Opens a file for appending in binary format. The file pointer is at the end of the file if the file exists. That is, the file is in the append mode. If the file does not exist, it creates a new file for writing. a+ Opens a file for both appending and reading. The file pointer is at the end of the file if the file exists. The file opens in the append mode. If the file does not exist, it creates a new file for reading and writing. ab+ Opens a file for both appending and reading in binary format. The file pointer is at the end of the file if the file exists. The file opens in the append mode. If the file does not exist, it creates a new file for reading and writing. buffering - If the buffering value is set to 0, no buffering takes place. If buffering value is 1, line buffering is performed while accessing a file. If you specify the buffering value as an integer greater than 1, then buffering action is performed with the indicated buffer size. If negative, the buffer size is the system default(default behavior). """ help(open) try: fo = open("missing.txt") except Exception as e: print( "Produces a: FileNotFoundError: [Errno 2] No such file or directory: 'missing.txt'" ) print(type(e)) print(e) try: fo = open("missing.txt", "r") except Exception as e: print("The line above is the same as the line below:") print(type(e)) print(e) # A file does not need to exist for you fo = open("python.txt", "w") # fo is a file-handler object print(type(fo)) # fo has lots of methods for interacting with it's file: print(dir(fo)) # For example, fo has a .name .close, .mode, .write, .close, etc. print("Name of the file: ", fo.name) print("Closed or not : ", fo.closed) print("Opening mode : ", fo.mode) fo.write("Python is a great language.\nYeah its great!!\n") fo.write("Python is a great language.\nYeah its great!!\n") fo.write("Python is a great language.\nYeah its great!!\n") fo.write("Python is a great language.\nYeah its great!!\n") fo.close() # Show python.txt in text editor fo = open("python.txt", "r") """ Below, passed parameter is the number of bytes to be read from the opened file. Method starts reading from the beginning of a file and if count is missing, then it tries to read as much as possible, maybe until the end of file. This is more commonly used with binary files. """ string_import = fo.read(10) print("Read String is : ", string_import) # For a text file, reads one line, progressively as called repeatedly. flines = fo.readline() print(flines) wholefile = fo.read() print(wholefile) # Files should be closed when done! fo.close() fo = open("python.txt", "r") # For a text file, returns a List with each line as a string element. all_lines = fo.readlines() print(all_lines) # Files should be closed when done! fo.close() f = open("workfile", "w") f.write("hey") f.write("hey\n") f.write("hey") print(f.closed) print(f.mode) print(f.name) f.close() print(f.closed) # Show workfile in text editor # Show mbox-short.txt in text editor fhand = open("mbox-short.txt") count = 0 for line in fhand: count = count + 1 print(line) print("Line Count:", count) fhand.close() # searching through a file fhand = open("mbox-short.txt") for line in fhand: line = line.rstrip() if line.startswith("From:"): print(line) fhand.close() # Let user choose the name fname = input("Enter the file name: ") # mbox-short.txt fhand = open(fname) count = 0 for line in fhand: if line.startswith("Subject:"): count = count + 1 print("There were", count, "subject lines in", fname) print(fhand.closed) fhand.close() # Try and catch are helpful here: fname = input("Enter the file name: ") # mbox-short.txt try: fhand = open(fname) except Exception as e: print(e, ", File cannot be opened:", fname) count = 0 for line in fhand: if line.startswith("Subject:"): count = count + 1 print("There were", count, "subject lines in", fname) # using open is ok, but can cause issues if you crash before closing a file. f = open("workfile") for line in f: print(line, end="") # raise Exception # would cause the file not to be closed f.close() print(f.closed) f.close() # While you could use exception handling to deal with the above issue, # beter practice is to use the "with" statement to open a file, # execute a block of statements, and automatically close file when complete. with open("workfile") as f: read_data = f.read() # raise Exception # and the file would still close just fine print(f.closed) print(read_data) """ If you’re not using the "with" keyword, then you should call f.close() to close the file and immediately free up any system resources used by it. If you don’t explicitly close a file, Python’s garbage collector will eventually destroy the object and close the open file for you, but the file may stay open for a while. Another risk is that different Python implementations will do this clean-up at different times. The with statement creates a context manager, which manages the usage of a resource, like a file, by performing setup and teardown operations. For files, the teardown operation is automatic closure. Forgetting to close a file can sometimes cause problems. For example, a file opened in write mode cannot be written to by other programs Good practice is to use a with statement when opening files, to guarantee that the file is closed when no longer needed. This is is best for read and write: """ with open("python.txt", "w") as f: f.write("some data to be written to the file") data = "some data to be written to the file \n" f.write(data) data = "some data to be written to the file" f.write(data) # Show data.txt in text editor with open("data.txt", "r") as f: data = f.read() print(data) # If you don't use with (which is clearly better), then you should do this: reader = open("data.txt") try: # Further file processing goes here print(reader.read()) raise Exception except Exception as e: print("something broke: ", type(e), e) finally: reader.close() reader.closed # +++++++++++++++++ Cahoot-18.1 # https://mst.instructure.com/courses/58101/quizzes/56956 # If you're curious about how the context manager 'with' works, # you can creat an object capable of being handled by with this way: class MyFileOpener(object): """ An example of how to re-create your own object for use with the with File(..) as syntax. """ def __init__(self, file_name, method): print("init") self.file_obj = open(file_name, method) def __enter__(self): print("enter") return self.file_obj def __exit__(self, type, value, traceback): print("exit closing") self.file_obj.close() # Step in debugger here with MyFileOpener("demo.txt", "w") as opened_file: opened_file.write("Hola!") # Show demo.txt in text editor # Writing other objects to a file contents = {"aa": 12, "bb": 21, "list": [1, 2, 3]} print(contents) repr(contents) str(contents) print(repr(contents)) print(str(contents)) with open("myfile1.txt", "w+") as file: file.write(str(contents)) # writes a string to a file # Show myfile1.txt in text editor # https://en.wikipedia.org/wiki/JSON import json with open("myfile2.txt", "w+") as file: file.write(json.dumps(contents)) # writes an object to a file # Show myfile2.txt in text editor # Reading from a file with open("myfile1.txt", "r+") as file: contents = file.read() # reads a string from a file print(contents) print(type(contents)) # print: {"aa": 12, "bb": 21} # Note is this easily recoverable? with open("myfile2.txt", "r+") as file: contents = json.load(file) # reads a json object from a file print(contents) print(type(contents)) # print: {"aa": 12, "bb": 21} # Note: this is recoverable! # open n files at once! d_path = "data.txt" d_r_path = "data_reversed.txt" with open(d_path, "r") as reader, open(d_r_path, "w") as writer: dog_breeds = reader.readlines() writer.writelines(reversed(dog_breeds)) # flush """ The flush() file method can be called to force the interpreter to flush the output buffer to disk. Output to a file is buffered by the interpreter before being written to the computer's hard disk. By default, data is line-buffered, e.g., data is written to disk only when a newline character is output. There may be a delay between a call of write() and that data actually being written to the disk. """ import os # Open a file with default line-buffering. with open("myfile.txt", "w") as f: # No newline character, so not written to disk immediately f.write("Write me to a file, please!") # file not really written yet here f.write("\n") # Force output buffer to be written to disk f.flush() # file written here f.write("more") # +++++++++++++++++ Cahoot-18.2 # https://mst.instructure.com/courses/58101/quizzes/56957 """ Pickling data for later consumption Useful to store arbitrary objects to a file. Not safe or fast! """ import pickle help(pickle) help(pickle.dump) help(pickle.load) li = [1, None, "Stan", {"thing": 1}] pickle.dump(li, open("test.pkl", "wb")) # peek at raw pickle file now imported_li = pickle.load(open("test.pkl", "rb")) # Totally recoverable data """ A pickle file can contain essentially any python objects. Pickle files can thus include malicious payloads. Don't just import any random pickle you find on the internet! It could have harmful code in it, that would run arbitrary commands when you try to import it. If you really really want to handle suspect code (i.e., a pickle), opening it in a contained environment is one way to mitigate risks... """ """ CSV files! The original spreadsheet. Incredibly common. While you can read these as raw text and parse yourself, there are many module imports that do it for you. We'll cover the csv module now, and pandas later. """ import csv print(dir(csv)) help(csv) # show employee_birthday.csv in vim # show employee_birthday.csv in libreoffice with open("employee_birthday.csv") as csv_file: csv_reader = csv.reader(csv_file, delimiter=",") line_count = 0 for row in csv_reader: print(row) with open("employee_birthday.csv") as csv_file: csv_reader = csv.DictReader(csv_file, delimiter=",") line_count = 0 for row in csv_reader: print(row) # writing functionality of csv module with open("employee_birthday.csv", mode="a") as employee_file: employee_writer = csv.writer(employee_file, lineterminator="\n") employee_writer.writerow(["John Smith", "Accounting", "November"]) employee_writer.writerow(["Erica Meyers", "IT", "March"]) # write from dictionary with open("employee_file2.csv", mode="w") as csv_file: fieldnames = ["emp_name", "dept", "birth_month"] writer = csv.DictWriter(csv_file, fieldnames=fieldnames) writer.writeheader() writer.writerow( {"emp_name": "John Smith", "dept": "Accounting", "birth_month": "November"} ) writer.writerow({"emp_name": "Erica Meyers", "dept": "IT", "birth_month": "March"}) # +++++++++++++++++ Cahoot-18.3 # https://mst.instructure.com/courses/58101/quizzes/56957