我花了几个月的时间从头开始重写我的Python算法的新版本。我的目标之一是编写一个完整的文档代码,易于阅读和理解“任何人”。
在同一个项目文件夹中,我放了很多不同的模块,每个模块都包含一个类。我使用类作为函数和相关变量容器,这样一个类包含具有特定任务的所有函数,例如在Excel文件上写入算法的所有输出结果。
这是一个例子:
Algorithm.py
import os
import pandas as pd
import numpy as np
from Observer import Observer
def main(hdf_path):
for hdf_file in os.listdir(hdf_path):
filename = str(hdf_file.replace('.hdf', '.xlsx'))
Observer.create_workbook(filename)
dataframe = pd.read_hdf(hdf_file)
years_array = dataframe.index.levels[0].values
for year in years_array:
year_mean = np.mean(dataframe.loc[year].values)
Observer.mean_values = np.append(Observer.mean_values, dataframe_mean)
Observer.export_result()
if __name__ == "main":
hdf_path = 'bla/bla/bla/'
main(hdf_path)
Observer.py
import numpy as np
import openpyxl
class Observer:
workbook = None
workbookname = None
mean_values = np.array([])
def create_workbook(filename):
Observer.workbook = openpyxl.Workbook()
Observer.workbookname = filename
# do other things
def save_workbook():
Observer.workbook.save('results_path' + Observer.workbookname)
def export_results():
# print Observer.mean_values values in different workbook cells
# export result on a specific sheet
我希望你能从这个简单的例子中理解我如何在我的项目中使用class。对于每个类,我定义了很多变量(例如工作簿),我从其他模块中调用它们就好像它们是全局变量一样。通过这种方式,我可以从任何地方轻松访问它们,我不需要将它们明确地传递给函数,因为我可以简单地编写Classname.varname。
我的问题是:设计不好吗?它会造成一些问题或性能下降吗?
感谢您的帮助。
答案 0 :(得分:2)
我的问题是:设计不好吗?
是。
我可以简单地编写Classname.varname。
当您强制执行调用Classname.varname
时,您在类之间创建了非常强大的coupling。访问此变量的类现在与Classname
强烈耦合。这可以防止您通过传递不同的参数来改变OOP方式的行为,并且会使类的测试复杂化 - 因为您将无法模拟Classname
并使用其模拟而不是“真正的”类。
当您尝试在应用的两个部分中运行2个非常相似的代码时,这将导致代码重复,这些代码仅在这些参数中有所不同。您最终将创建两个几乎相同的类,一个使用Workbook
,另一个使用Notepad
类。
记住恶性循环:
Hard to test code -> Fear of refactor -> Sloppy code
^ |
| |
---------------------------------------
使用适当的对象,能够模拟它们(以及dependency injection)将保证您的代码易于测试,其余的将会跟随。