这是我第一次发布堆栈溢出,所以如果我做错了,我会道歉。
我试图了解构建Python模块的最佳方法。作为一个例子,我制作了一个同步源和目标的备份模块,只有在源和目标之间存在差异时才复制文件。备份模块仅包含名为Backup的类。
现在我被告知OOP是有史以来最伟大的事情,但这似乎是错误的。在查看了一些标准库源代码之后,我发现大多数内容都没有分成一个类。我试图对此做一些研究,以确定何时应该使用一个类,何时我应该只有函数,并且我得到了不同的信息。我想我的主要问题是,如果下面的代码留作一个类,或者它应该只是一个带有函数的模块。目前非常简单,但我可能希望将来增加更多。
"""Class that represents a backup event."""
import hashlib
import os
import shutil
class Backup:
def __init__(self, source, destination):
self.source = source
self.destination = destination
def sync(self):
"""Synchronizes root of source and destination paths."""
sroot = os.path.normpath(self.source)
droot = os.path.normpath(self.destination) + '/' + os.path.basename(sroot)
if os.path.isdir(sroot) and os.path.isdir(droot):
Backup.sync_helper(sroot, droot)
elif os.path.isfile(sroot) and os.path.isfile(droot):
if not Backup.compare(sroot, droot):
Backup.copy(sroot, droot)
else:
Backup.copy(sroot, droot)
def sync_helper(source, destination):
"""Synchronizes source and destination."""
slist = os.listdir(source)
dlist = os.listdir(destination)
for s in slist:
scurr = source + '/' + s
dcurr = destination + '/' + s
if os.path.isdir(scurr) and os.path.isdir(dcurr):
Backup.sync_helper(scurr, dcurr)
elif os.path.isfile(scurr) and os.path.isfile(dcurr):
if not Backup.compare(scurr, dcurr):
Backup.copy(scurr, dcurr)
else:
Backup.copy(scurr, dcurr)
for d in dlist:
if d not in slist:
Backup.remove(destination + '/' + d)
def copy(source, destination):
"""Copies source file, directory, or symlink to destination"""
if os.path.isdir(source):
shutil.copytree(source, destination, symlinks=True)
else:
shutil.copy2(source, destination)
def remove(path):
"""Removes file, directory, or symlink located at path"""
if os.path.isdir(path):
shutil.rmtree(path)
else:
os.unlink(path)
def compare(source, destination):
"""Compares the SHA512 hash of source and destination."""
blocksize = 65536
shasher = hashlib.sha512()
dhasher = hashlib.sha512()
while open(source, 'rb') as sfile:
buf = sfile.read(blocksize)
while len(buf) > 0:
shasher.update(buf)
buf = sfile.read(blocksize)
while open(destination, 'rb') as dfile:
buf = dfile.read(blocksize)
while len(buf) > 0:
dhasher.update(buf)
buf = dfile.read(blocksize)
if shasher.digest() == dhasher.digest():
return True
else:
return False
我认为它作为一个类没有意义,因为唯一的方法是同步。另一方面,备份是真实世界的对象。这真让我困惑。
作为一些方面的问题。我的同步方法和sync_helper函数看起来非常相似,可能有可能以某种方式将两者合并(我将其留作自己的练习),但这通常是如何在使用需要某个初始状态的递归函数时完成的。意思是,可以在一个函数中执行某些操作以达到某个状态,然后调用执行实际操作的递归函数。这看起来很乱。
最后,我有一堆实用程序函数,它们实际上不是对象的一部分,但是由sync使用。将这些分解为像实用程序子模块或不引起混淆的事情会更有意义吗?
构建我的程序对我来说是最令人困惑的事情,任何帮助都会非常感激。
答案 0 :(得分:0)
这种方法(以及其他几种方法)是错误的:
def copy(source, destination):
"""Copies source file, directory, or symlink to destination"""
它的工作方式(Backup.copy(scurr, dcurr)
),但在实例上使用时不起作用。
Python中的所有方法都应该将self
作为第一个位置参数:def copy(self, source, destination)
,或者应该转换为staticmethod
(或移出类)。
使用staticmethod
装饰器声明静态方法:
@staticmethod
def copy(source, destination):
"""Copies source file, directory, or symlink to destination"""
但在这种情况下,source
和destination
实际上是Backup
个实例的属性,因此可能应修改它以使用属性:
def copy(self):
# use self.source and self.destination