Create a folder structure as this: py_pkg/reader/
reader module in reader package, has a class called Reader py_pkg/reader/reader.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| # class has three methods: "init", "close" and "read".
class Reader:
#It takes a parameter "filename" which is used to open a file in read mode ('rt')
def __init__(self, filename):
# assigns the file object to an instance variable called "f".
self.f = open(filename, 'rt')
# close method calls the "close" method on the file object stored in the instance variable "f".
def close(self):
self.f.close()
# The "read" method is used to read the contents of the file opened in the constructor.
def read(self):
# returns the result of calling the "read" method on the file object stored in the instance variable "f".
return self.f.read()
|
Test it
1
2
3
4
5
| >>> import reader.reader
>>> f = reader.reader.Reader('LICENSE.md')
>>> f.read()
'Copyright (c) 2023 Victor Ma\n\n## Blog Infrastructure...'
>>> f.close()
|
After import Reader class into the reader package by py_pkg/reader/__init__.py
1
2
3
| # from package reader's module reader.py, import Reader class.
from reader.reader import Reader
# Now Reader class is putting directly under reader package
|
Test it again
1
2
3
4
5
| >>> import reader # imported reader package
>>> f= reader.Reader('LICENSE.md')
>>> f.read()
'Copyright (c) 2023 Victor Ma\n\n## Blog Infrastructure...'
>>> f.close()
|
subpackage structure as this: py_pkg/reader/compressed
Create a subpackage called compressed and a module gzipped.py
1
2
3
4
5
6
7
8
9
10
11
12
13
| import gzip
import sys
opener = gzip.open
# common way to check if the current script is being executed as the main program or if it is being imported as a module in another program.
if __name__ == '__main__':
# opens a gzip file for writing using the first command-line argument passed to the script (sys.argv[1]) as the file path.
f = gzip.open(sys.argv[1], mode='wt')
# writes a single string to the file, which is obtained by joining all the command-line arguments starting from the third (sys.argv[2:]) with a space character.
f.write(' '.join(sys.argv[2:]))
f.close()
|
Test each package, subpackage and module can be importted
1
2
3
4
| >>> import reader
>>> import reader.reader
>>> import reader.compressed
>>> import reader.compressed.gzipped
|
Test calling the module directly to create a gzipped file
1
2
3
| $ python3 -m reader.compressed.gzipped test.gzip Content compressed by gzip
$ file test.gzip
test.gzip: gzip compressed data, was "test.gzip", last modified: Sat Feb 18 20:03:35 2023, max compression, original size modulo 2^32 26
|
Just for the fun of it, create a bzipped module to handle bz2 file, and test
1
2
3
4
5
6
7
8
9
| import bz2
import sys
opener = bz2.open
if __name__ == '__main__':
f = bz2.open(sys.argv[1], mode='wt')
f.write(' '.join(sys.argv[2:]))
f.close()
|
Call the compressed helpper module from Reader class
Change the reader module like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| import os # used to get file extension, to decide which compressed moudle to call
# import both compressed module together
from reader.compressed import gzipped,bzipped
# creat a dict to map extension to their opener functions
extension_map = {
'.gzip': gzipped.opener,
'.bz2': bzipped.opener,
}
# class has three methods: "init", "close" and "read".
class Reader:
#It takes a parameter "filename" which is used to open a file in read mode ('rt')
def __init__(self, filename):
# get the filename's extension
extension = os.path.splitext(filename)[1]
# define opener function to choose from the dictrionary
# or fall back to the default python built-in fuction "open"
opener = extension_map.get(extension, open)
# assigns the file object to an instance variable called "f".
self.f = opener(filename, 'rt')
|
Test it out
1
2
3
4
5
6
7
8
9
| >>> import reader.reader
>>> f = reader.Reader('test.gzip')
>>> f.read()
'Content compressed by gzip'
>>> f.close()
>>> f = reader.Reader('test.bz2')
>>> f.read()
'Content compressed by bz2'
>>> f.close()
|