I am learning Python and I know that a lot of my future projects will be based on files and managing them. How does this look? Is anything in here redundant or overcomplicated?
import os
import zipfile
import shutil
from datetime import datetime as dt
class File:
def __init__(self, path, datetime=True):
self.path = path
self.datetime = datetime
self.abs_path = os.path.abspath(self.path)
self._dt_manager = lambda prop: prop if not self.datetime else dt.fromtimestamp(prop)
self._os_path = lambda func, path_=self.abs_path, *args, **kwargs: getattr(os.path, func)(path_, *args, **kwargs)
self.readable = False
self.data = None
self.lines = None
self.line_count = None
try:
with open(self.path, "r") as target:
self.data = target.read()
self.lines = self.data.splitlines()
self.line_count = len(self.lines)
self.readable = True
except UnicodeDecodeError:
pass
self.size_in_bytes = self._os_path("getsize")
self.size = self.format_size(self.size_in_bytes)
self.created = self._dt_manager(self._os_path("getctime"))
self.last_modified = self._dt_manager(self._os_path("getmtime"))
self.last_accessed = self._dt_manager(self._os_path("getatime"))
self.full_name = self._os_path("basename")
self.name, self.extension = self._os_path("splitext", self.full_name)
self.dir_path = self._os_path("dirname")
self.dir_name = self._os_path("basename", self.dir_path)
def __repr__(self):
return "<File {}>".format(self.full_name)
def __str__(self):
return self.abs_path
def __getitem__(self, index):
return self.lines[index]
def __iter__(self):
return self.data
def __eq__(self, other):
return self.abs_path == (other.abs_path if isinstance(other, File) else other)
def __len__(self):
return self.line_count
@staticmethod
def format_size(size_in_bytes, suffix="B"):
for unit in ["", "K", "M", "G", "T"]:
if abs(size_in_bytes) < 1024.0:
return str(size_in_bytes) + unit + suffix
size_in_bytes /= 1024.0
return str(size_in_bytes) + "Y" + suffix
def unzip(self, location=None):
if location is None:
location = self.dir_path
with zipfile.ZipFile(self.abs_path, "r") as target:
return target.extractall(location)
def rename(self, new_name):
return os.rename(self.abs_path, new_name)
def copy(self, location=None, new_name=None):
if location is None:
location = self.abs_path
return shutil.copy(self.abs_path, location if not new_name else location + new_name)
def duplicate(self, amount=1, splitter="-"):
duplicate_name = lambda index: self.name + splitter + str(index) + self.extension
if amount > 1:
for i in range(0, amount):
self.copy(duplicate_name(i))
return None
return self.copy(duplicate_name(0))
def delete(self):
return os.remove(self.abs_path)
def find(self, query):
return [line for line in self.lines if query in line]