我有以下基类:
class ClientRepo(Repository):
def __init__(self) -> None:
self.__clientList = []
def hasClientWithId(self, clientId):
for client in self.__clientList:
if client.getId() == clientId:
return True
return False
def addClient(self, client):
if type(client).__name__ == 'ClientDAO':
if not self.hasClientWithId(client.getId()):
client.setClientId(self.__maximumIndexInClientList() + 1)
self.__clientList.append(client)
else:
raise ObjectAlreadyInCollectionException
else:
raise TypeError
它基本上只包含一个列表,可以向其中添加ClientDAO。你知道吗
以及由此衍生出的:
class ClientFileRepository(ClientRepo):
def __init__(self, fileName) -> None:
super().__init__()
self.__fileName = fileName
self.__file = None
def hasClientWithId(self, clientId):
self.__loadRepo()
hasClientWithId = super().hasClientWithId(clientId)
super().clean()
return hasClientWithId
def addClient(self, client):
self.__loadRepo()
super().addClient(client)
self.__storeRepo()
super().clean()
def __loadFileReadMode(self):
self.__file = open(self.__fileName, "r")
def __loadFileWriteMode(self):
self.__file = open(self.__fileName, "w")
def __closeFile(self):
self.__file.close()
def __loadRepo(self):
self.__loadFileReadMode()
for line in self.__file:
splitLine = line.split()
clientToAdd = ClientDAO(splitLine[1])
clientToAdd.setClientId(int(splitLine[0]))
super().addClientWithId(clientToAdd)
self.__closeFile()
def __storeRepo(self):
self.__loadFileWriteMode()
self.__file.write("")
for client in super().getList():
self.__file.write(self.clientToString(client))
self.__closeFile()
def clientToString(self, clientDAO):
return str(clientDAO.getId()) + " " + clientDAO.getName() + "\n"
一个类,它应该从文件中加载列表,从父级调用addClient
,并将更新后的列表存储在文件中。问题是,在子类加载addClient
中的文件之后,它再次从子类调用父类中的方法hasClientWithId
。但是我希望它调用hasClientWithId
,从父级,也就是它所在的上下文。我能做到吗?你知道吗
我能想出几种方法来实现你的目标。我把他们从最差排到最好
<强>1。完全符合您的要求
您希望
ClientRepo.addClient
调用ClientRepo.hasClientWithId
,而不是ClientFileRepository.hasClientWithId
。可以强制执行:这不是一个好方法,因为它不直观,并且违反了面向对象的原则。任何其他编写重写
hasClientWithId
的ClientRepo
子类的程序员都会期望这会对hasClientWithId
的每个调用产生影响,甚至在addClient
内部<强>2。让
ClientFileRepository
决定使用哪个函数添加变量
在
ClientFileRepository.__init__
中,打开文件时将其设置为True
,关闭文件时将其设置为False
。然后将ClientFileRepository
中的hasClientWithId
更改为以避免再次打开同一个文件。这是可行的,但是为这个类编写新函数是相当困难的,因为您总是需要知道函数调用是来自您的类内部还是其他地方的调用。而且,这看起来效率很低,因为即使只添加一个客户机,也要读写整个文件。你知道吗
3岁。只读取一次文件并修改底层
ClientRepo
这显然是假设在调用
addClient
之间文件没有被其他人更改,并且程序仍然会为每个addClient
覆盖整个文件。如果这对您来说是个问题,那么最好是明确地公开loadRepo
和storeRepo
。然后使用这个类的程序员可以决定何时加载和保存是必要的和有用的。您可以为此使用上下文管理器。你知道吗额外:读取并保存每个方法的文件
您可以使用函数修饰符来使用解决方案2,而无需为每个函数编写相同的代码:
在这里要小心,使用它不是很直观。例如,
self.__isFileOpen
是在__init__
中定义的,但是下面的方法都没有直接使用它。相反,它的用法隐藏在loadAndStore
装饰器中。你知道吗结尾有一些提示:
type(client).__name__ == 'ClientDAO'
是坏习惯。使用isinstance(client, ClientDAO)
完全采用OOP__fileName
这样的私有变量通常被认为是不必要的,只要在变量前面加一个下划线就可以表示“内部使用”。函数也是如此。你知道吗相关问题 更多 >
编程相关推荐