跳转至主要内容

Python编程

Python设计模式在实际项目中的应用

Sprite
发表于 2023年10月15日
设计模式是软件设计中常见的解决问题的可重复的方案。它们提供了一套经过验证的方法,用于解决特定类型的问题。设计模式有助于提高代码的可维护性和复用性,并促进开发团队之间的沟通和理解。
使用设计模式可以帮助开发人员更好地组织和结构化他们的代码,并提供一种标准化的方式来解决常见的设计问题。通过遵循设计模式,开发人员可以减少重复的工作,提高代码的复用性,并提高系统的可维护性和可扩展性,下面介绍4种我在实际项目中常用到设计模式

工厂模式

工厂模式是我最喜欢的设计模式之一,因为它抽象了对象创建的过程,并将创建对象的责任委托给其子类。通常使用一个基类(即工厂)来实现,其中包含一个负责创建不同类型对象的工厂方法。

小贴士💡:当我负责设计一个类的接口时,我发现工厂模式特别方便。我的同事们协助实现了该类的各种用例。它提供了一种结构化和高效的协作方式,使每个团队成员能够专注于自己指定的任务,同时遵循一致的接口。

工厂模式的常见用例如下:

文件解析:如果我们的应用程序需要从各种文件格式(如CSV、JSON、XML等)中读取数据,我们可以使用工厂模式来创建文件解析器对象。每个解析器类可以处理特定文件格式的数据解析,工厂可以根据文件扩展名或内容来确定使用哪个解析器。以下是一个示例:

import pandas as pd

class FileParser:
def parse(self, file_path):
pass

class CSVFileParser(FileParser):
def parse(self, file_path):
return pd.read_csv(file_path)

class JSONFileParser(FileParser):
def parse(self, file_path):
with open(file_path, "r") as file:
return json.load(file)

class FileParserFactory:
def create_parser(self, file_path):
if file_path.endswith(".csv"):
return CSVFileParser()
elif file_path.endswith(".json"):
return JSONFileParser()
else:
raise ValueError("Unsupported file format")

# Usage
file_path = "data.csv"
parser_factory = FileParserFactory()
parser = parser_factory.create_parser(file_path)
data = parser.parse(file_path)

小贴士💡:每当我们遇到需要一个统一的接口来执行不同实现的各种操作的情况时,工厂模式就派上用场了。这种模式不仅对处理各种数据预处理任务有益,还可以创建各种可视化效果并执行其他需要具有不同底层处理过程的任务,以保持一致的接口。


外观模式

外观模式为复杂的子系统或一组类提供了一个简单而统一的接口。它允许我们通过一个单一的高级接口与系统进行交互,而无需处理子系统组件的底层复杂性。

小贴士💡:我经常使用外观模式来创建一组共享函数或便利类,用于执行算法中涉及的各个步骤。这些函数或类封装了数据预处理、算法训练和评估等任务,提供了简化和统一的接口。

from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
from helper import Preprocessor

class MachineLearningFacade:
def __init__(self, dataset, target_column):
self.dataset = dataset
self.target_column = target_column

def preprocess_data(self):
# 预处理数据集
X = self.dataset.drop(columns=[self.target_column])
y = self.dataset[self.target_column]
preprocessor = Preprocessor(X,y)
X, y = preprocessor.scale(X,y)
X, y = preprocessor.normalize(X,y)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
return X_train, X_test, y_train, y_test

def train_model(self, X_train, y_train):
# 训练模型
model = LogisticRegression()
model.fit(X_train, y_train)
return model

def evaluate_model(self, model, X_test, y_test):
# 评估模型
y_pred = model.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
return accuracy

def start_training(self):
# 整合上面的函数
X_train, X_test, y_train, y_test = self.preprocess_data(self)
model = self.train_model(X_train, y_train)
return self.evaluate_model(model, X_test, y_test)


装饰器模式

装饰器模式是一种结构型设计模式,它允许在运行时动态和灵活地扩展对象的行为。它能够在不修改对象代码的情况下,为单个对象添加新的功能或责任。

我们可以通过创建一组装饰器类来实现这一点,这些类包装核心对象并逐步添加所需的功能。每个装饰器都遵循与核心对象相同的接口,确保多个装饰器的兼容性和无缝组合。

class SentimentAnalyzer:
def analyze_sentiment(self, text):
print(text)
return "Neutral"

class RemovePunctuationDecorator:
def __init__(self, sentiment_analyzer):
self._sentiment_analyzer = sentiment_analyzer

def analyze_sentiment(self, text):
import string
text = text.translate(str.maketrans("", "", string.punctuation))
return self._sentiment_analyzer.analyze_sentiment(text)

class RemoveStopwordsDecorator:
def __init__(self, sentiment_analyzer):
self._sentiment_analyzer = sentiment_analyzer
self.stopwords = set(["a", "an", "the", "in", "on", "of", "for"])

def analyze_sentiment(self, text):
words = text.split()
filtered_words = [word for word in words if word.lower() not in self.stopwords]
text = " ".join(filtered_words)
return self._sentiment_analyzer.analyze_sentiment(text)

if __name__ == "__main__":
# 创建一个 SentimentAnalyzer 对象
sentiment_analyzer = SentimentAnalyzer()

# 添加不同的装饰器
sentiment_analyzer = RemovePunctuationDecorator(sentiment_analyzer)
sentiment_analyzer = RemoveStopwordsDecorator(sentiment_analyzer)

# 开始分析文本
text = "This is a great movie! I loved it."
result = sentiment_analyzer.analyze_sentiment(text)
print("Sentiment:", result)
# Output: This is great movie I loved it n Sentiment: Neutral

文本通过单个函数在多个对象之间进行顺序处理,从而实现代码减少和优雅设计。

小贴士💡:装饰器非常有用,还可以以一种非常棒的方式扩展函数的功能。可以查看我的帖子了解更多信息。

单例模式

单例设计模式也是一种创建型设计模式,它通过应用程序确保一个类只有一个实例,并提供对该实例的全局访问点。

在实际应用中,当处理资源密集型类的初始化或确保类的多个实例不存在以防止潜在错误时,这种模式非常有用。在Python中,许多包已经为我们应用了这种模式,所以我们不必担心它,以下是一些例子:

  1. 日志模块( logging ):标准的Python日志模块, logging ,可被视为用于日志记录目的的单例。您可以全局配置它并从应用程序的任何部分访问它。

  2. 数据库连接:一些数据库库(如 SQLAlchemy )可以以单例的方式处理连接,以确保整个应用程序只使用一个数据库连接。

  3. 缓存库:一些缓存库(如 cachetools )可能使用类似单例的行为,以确保应用程序中只使用一个缓存实例。

我们可以通过在类中重写 __new__() 方法来模拟Python中的单例行为。 __new__() 是一个特殊的方法,在创建类的实例时被调用。在这种情况下,该方法检查类的 _instance 属性是否 None 。如果是,它使用 super() 函数创建一个新的实例并将其存储在 _instance 属性中。如果不是,则返回另一个实例。

class SingletonClass:
_instance = None

# 重写__new__方法
def __new__(cls):
if cls._instance is None:
# 创建一个实例当且仅当这个类从未被初始化
cls._instance = super(SingletonClass, cls).__new__(cls)
return cls._instance
def some_method(self):
print("This is a method inside the SingletonClass")
# 调用类创建两个实例
singleton1 = SingletonClass()
singleton2 = SingletonClass()
# 检验结果,两个实例是相同的,都指向同一个reference
print(singleton1 is singleton2) # Output: True


提示💡:使用GCP上的AI平台开发自定义实验记录类时,我使用了这种模式,以避免需要将日志组件传递给所有类,并减少不必要的代码。

结论

总之,Python设计模式,包括单例模式、装饰器模式、外观模式和工厂模式,为常见的编程挑战提供了强大而灵活的解决方案,提升了应用程序的整体架构和可维护性。

单例模式使我们能够确保一个类的单一共享实例。装饰器模式通过允许我们在运行时向对象添加新的责任,促进了动态功能扩展。

外观模式通过提供统一且用户友好的接口来简化复杂的子系统,而工厂模式则抽象了对象的创建过程,允许子类决定要实例化的对象类型。

通过应用这些设计模式,我们可以实现更清晰、更可扩展和可维护的代码。每个模式都解决了特定的挑战,并为解决各种现实世界的编程问题提供了有价值的工具,从而打造出优雅高效的解决方案。

评论已关闭。