电商网站建设常见问题,国家信用信息公示系统贵州,色轮 网站,国产服务器系统免费的有哪些一、Python策略模式介绍
Python策略模式#xff08;Strategy Pattern#xff09;是一种软件设计模式#xff0c;用于通过将算法封装为独立的对象#xff0c;而使得它们可以在运行时动态地相互替换。该模式使得算法的变化独立于使用它们的客户端#xff0c;从而达到代码的…一、Python策略模式介绍
Python策略模式Strategy Pattern是一种软件设计模式用于通过将算法封装为独立的对象而使得它们可以在运行时动态地相互替换。该模式使得算法的变化独立于使用它们的客户端从而达到代码的可扩展性、灵活性和可维护性。
功能 1.将不同算法进行抽象和封装使得它们可以互相替换从而增强程序的可扩展性。 2.将算法的变化独立于客户端使得客户端代码不需要修改即可使用不同的算法。 3.提高程序的可读性和可维护性。 优点 1.代码可扩展性和灵活性好能够适应不同的需求。 2.降低模块之间的耦合度提高代码的可维护性和可读性。 3.具有良好的可扩展性可以动态地增加、删除或替换算法。 缺点 1.会增加一定的复杂度需要额外的类定义。 2.可能会导致系统中出现较多的类增加系统的复杂度。 3.需要客户端了解不同策略的差异才能选择合适的策略。 应用场景 1.需要在运行时根据不同情况选择不同算法的场景。 2.需要封装业务逻辑的场景。 3.需要对同一种算法进行多次修改的场景。 使用方式 1.抽象出一个策略接口定义策略的方法。 2.将不同的算法分别封装为具体的策略类并实现策略接口的方法。 3.创建一个策略上下文类负责调用不同的策略根据不同的需求选择合适的策略。 在应用程序开发中的应用 1.实现排序算法将排序逻辑抽象出来将不同的排序算法封装为不同的策略然后在实现排序的过程中动态地选择不同的排序算法。 2.实现搜索算法将搜索算法封装为不同的策略然后在实现搜索的过程中动态地选择不同的搜索算法。 二、策略模式使用
工作原理
1.抽象策略类定义了一个公共接口用于所有策略类的实现。
2.具体策略类具体实现了策略接口的方法。
3.策略上下文类负责调用具体策略类的实例根据用户的需求选择相应的策略进行调用。
示例一实现不同促销活动
假设有一个电商平台需要实现多种促销活动来吸引用户购买商品。不同的促销活动有不同的算法例如满减、折扣、赠品等。这种情况下可以使用Python策略模式来实现。
首先定义一个促销策略接口PromotionStrategy定义促销活动的方法do_promotion
然后定义具体的促销策略类例如满减、折扣、赠品等。这里以满减和折扣为例
接下来定义促销上下文类PromotionContext负责调用不同的策略
最后可以在客户端代码中动态地选择不同的促销策略
# 定义促销策略接口
class PromotionStrategy():# 定义促销活动def do_promotion(self, price):pass# 定义具体促销策略
class ReductionPromotion(PromotionStrategy):# 满减def do_promotion(self, price):if price 200:return price -50return priceclass DiscountPromotion(PromotionStrategy): # 折扣def do_promotion(self, price):return price * 0.8# 定义上下文类负责调用不同的促销策略
class PromotionContext():def __init__(self, promotion_strategy:PromotionStrategy):self._promotion_strategy promotion_strategydef execute_promotion_strategy(self, price):return self._promotion_strategy.do_promotion(price)# 动态选择不同促销策略
promotion_type Reduction
promotion_type Discountif promotion_type Reduction:promotion_strategy ReductionPromotion()
elif promotion_type Discount:promotion_strategy DiscountPromotion()promotion_context PromotionContext(promotion_strategy)
final_price promotion_context.execute_promotion_strategy(100)
print(final_price)promotion_type Reduction
# promotion_type Discountif promotion_type Reduction:promotion_strategy ReductionPromotion()
elif promotion_type Discount:promotion_strategy DiscountPromotion()promotion_context PromotionContext(promotion_strategy)
final_price promotion_context.execute_promotion_strategy(200)
print(final_price)运行结果 80.0 150 上述代码中客户端代码通过promotion_type参数来选择不同的促销策略。然后将选择的策略传递给PromotionContext类由它来负责调用相应的促销策略。最终获得商品的最终价格final_price。如果需要增加或删除促销活动只需增加或删除相应的促销策略类即可不需要修改客户端代码。
示例二实现不同搜索算法
假设我们要实现一个搜索引擎支持多种搜索算法例如二分查找、线性查找、哈希查找等。为了实现这个功能我们可以使用策略模式将不同的搜索算法实现抽象成不同的类然后在运行时动态地将它们传递到搜索引擎中。具体的实现如下 # 定义算法类的抽象基类
class SearchAlgorithm():def search(self, array, target):pass# 定义算法二分法
class BinarySearch(SearchAlgorithm):def search(self, array, target):left, right 0,len(array) - 1 # 初始化二分法查找的左右边界此处0, 9。 相当于left0, rightlen(array)-1while left right:mid (left right) // 2if array[mid] target:return mid # 返回查找结果elif array[mid] target:left mid 1else:right mid -1return -1# 定义算法线性查找
class LineSearch(SearchAlgorithm):def search(self, array, target):for i in range(len(array)):if array[i] target:return ireturn -1# 定义搜索引擎
class SearchEngine():def __init__(self, search_algorithm):self.search_algorithm search_algorithmdef set_search_algorithm(self,search_algorithm):self.search_algorithm search_algorithmdef search(self,array, target):index self.search_algorithm.search(array, target) # 调用具体的搜索方法if index ! -1:print(fFound {target} at index {index})else:print(f{target} not found in the array.)# 测试代码
array [1,2,3,4,5,6,7,8,9,10]
target 5binary_search BinarySearch()
line_search LineSearch()search_engine SearchEngine(binary_search)
search_engine.search(array, target)search_engine SearchEngine(line_search)
search_engine.search(array, target)运行结果 Found 5 at index 4 Found 5 at index 4 在上面的例子中我们定义了一个SearchAlgorithm类它是所有搜索算法类的抽象基类。然后我们定义了两个具体的搜索算法类BinarySearch和LinearSearch它们分别实现了二分查找和线性查找算法。最后我们定义了一个SearchEngine类它接收一个具体的搜索算法类并将其存储在search_algorithm属性中。SearchEngine类还提供了search方法用于执行搜索操作。
在测试代码中我们首先创建了一个BinarySearch对象并用它来创建一个SearchEngine对象。然后我们调用search方法执行搜索操作结果显示目标值5被找到了。接着我们将search_algorithm属性设置为LinearSearch对象并再次调用search方法这次结果显示目标值5同样被找到了。
通过使用策略模式我们可以在运行时根据需要切换搜索算法而不需要修改搜索引擎的实现代码。这样就使得程序更加灵活和易于维护。
left, right 0, len(array) - 1
这行代码用于初始化二分查找的左右边界。在列表中查找某个元素时我们通常要在列表中的一段区间内进行查找。一开始这个区间通常是整个列表。那么左右边界要怎么确定呢
对于有序列表我们很容易想到的是将整个列表均匀地划分成两半然后查看中间位置的元素与目标元素的大小关系。如果中间位置的元素等于目标元素就返回对应的索引如果中间位置的元素小于目标元素就在右半边继续查找如果中间位置的元素大于目标元素就在左半边继续查找。这个过程就是二分查找。
而对于二分查找算法我们需要用left和right两个变量来表示当前查找区间的左右边界。一开始整个列表就是我们要查找的区间所以left的初始值为0right的初始值为列表长度减1。这样在每次查找时我们就可以根据left和right的值来确定当前查找区间的范围。
定义类时带括号和不带括号区别
在Python中定义类时可以带括号也可以不带括号。
语法格式为
class className:# some code here# 或者class className():# some code here带括号和不带括号的区别在于继承的方式不同。在Python 2.x版本中带括号和不带括号的定义方式有区别带括号的类定义方式是旧式类不带括号的类定义方式是新式类。而在Python 3.x版本中带括号和不带括号定义方式没有区别。
新式类和旧式类的主要区别在于继承方式不同。在旧式类中如果没有显式地指定一个特定的父类那么Python会默认继承由内置类型object派生出的类而在新式类中如果没有显式地指定一个特定的父类那么Python会默认继承内置类型object。
因此如果需要在Python 2.x版本中使用新式类建议在定义类时使用带括号的方式。在Python 3.x版本中则可以使用带括号或不带括号的方式定义类两种方式等效。
默认继承内置类型object
在Python中如果没有显式地指定一个特定的父类那么Python会默认继承内置类型object。下面是一个例子
class MyClass:passprint(type(MyClass)) # class type
print(type(MyClass())) # class __main__.MyClass在上面的例子中我们定义了一个空的类MyClass并没有指定父类。我们可以通过调用type()函数来查看MyClass的类型以及用MyClass()创建的实例的类型都是type和__main__.MyClass这说明Python默认继承了内置类型object。
如果我们明确指定了一个父类那么Python就会直接继承这个父类例如
class MyBaseClass:passclass MyClass(MyBaseClass):passprint(type(MyClass)) # class type
print(type(MyClass())) # class __main__.MyClass在上面的例子中我们定义了一个空的父类MyBaseClass并让MyClass类继承自MyBaseClass。此时MyClass的类型仍然是type但是MyClass()创建的实例的类型变为了__main__.MyClass这说明MyClass类已经从MyBaseClass类继承了一些属性和方法。