From afc5d7535baef8e334ac50774080e30b0bf5e465 Mon Sep 17 00:00:00 2001 From: slgxmh Date: Thu, 24 Jun 2021 00:09:55 +0800 Subject: [PATCH 1/9] =?UTF-8?q?=E4=BC=98=E5=8C=96=20python/abstract=5Ffact?= =?UTF-8?q?ory?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- python/creational/abstract_factor.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/python/creational/abstract_factor.py b/python/creational/abstract_factor.py index 8cae887..e582db2 100644 --- a/python/creational/abstract_factor.py +++ b/python/creational/abstract_factor.py @@ -1,9 +1,16 @@ +""" +抽象工厂模式: +抽象工厂提供了一个统一的接口,来创建一组相同功能的类。 + +这个例子设计的情景: +假设我们的系统需要加载不同数据集用于验证我们的模型,我们希望加载的数据集之间可以通过一个接口互相替换,不需要我们修改我们模型的代码。 +""" from typing import NoReturn, Type class DataSet(object): """ - 数据类的父类,抽象出这一类的最基本的要素与功能 + 数据类的父类,抽象出数据集这一类的最基本的要素与功能 属性: name: 所有的数据都有一个可读的名字,本例抽象出这一个属性做演示 @@ -77,7 +84,7 @@ class AbstractDataFactory(object): # 抽象工厂的核心思想:声明不同类型的工厂,生产出不同的类 -if __name__ == "__main__": +def main(): # 声明了一个文字类的数据集工厂 factory = AbstractDataFactory(Text) # 给这个数据集起名 NLP @@ -90,3 +97,7 @@ if __name__ == "__main__": data_set = factory.get_data_set("CV") # 查看 CV 数据集的内容 data_set.content() # Here is your data Image Image! + + +if __name__ == "__main__": + main() -- Gitee From 805e81392211a2aef089d08d78d76587fce0a06e Mon Sep 17 00:00:00 2001 From: slgxmh Date: Thu, 24 Jun 2021 14:03:40 +0800 Subject: [PATCH 2/9] change README --- README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/README.md b/README.md index e69de29..ba5d4b9 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,14 @@ +# 写作角度 +本人增删改查程序员出身,目前从事数据科学,看到一些数据科学从业者编程技能不足,同时也是为了提升自己的编程能力,顾计划站在数据科学的角度书写此书。 +# 适合人群 +已经熟悉Python基本语法及标准库,有简单的代码经验 +# 设计模式的作用 +在制作软件的过程中,设计模式可能是新手最容易忽略的基础技能,软件(脚本)没有良好的结构,在升级演进的过程一定会浪费需要时间。相应的,如果在软件建立的过程中,拥有可维护、易拓展的良好结构,那么一定有利于后续的升级开发。 +# 写作结构 +每一种设计模式先用极简的语言介绍核心思想 +再结合数据科学的实际情况,给出简洁的Python语言的实现 +结合代码解释具体思路 +说明这种模式的应用场景 +给出应用该设计模式的实例 +# 设计模式总结 +创建型的设计模式共有5种类型:工厂方法、抽象工厂、建造者、原型、单例 \ No newline at end of file -- Gitee From 4d31fbc22727b47821e4e93ad8d54de4f834dd3b Mon Sep 17 00:00:00 2001 From: slgxmh Date: Thu, 24 Jun 2021 15:12:31 +0800 Subject: [PATCH 3/9] =?UTF-8?q?=E4=BC=98=E5=8C=96pyhton/abstract=5Ffactory?= =?UTF-8?q?=E7=9A=84=E6=8F=8F=E8=BF=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- python/creational/abstract_factor.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/python/creational/abstract_factor.py b/python/creational/abstract_factor.py index e582db2..8761623 100644 --- a/python/creational/abstract_factor.py +++ b/python/creational/abstract_factor.py @@ -5,7 +5,7 @@ 这个例子设计的情景: 假设我们的系统需要加载不同数据集用于验证我们的模型,我们希望加载的数据集之间可以通过一个接口互相替换,不需要我们修改我们模型的代码。 """ -from typing import NoReturn, Type +from typing import Type class DataSet(object): @@ -19,7 +19,7 @@ class DataSet(object): def __init__(self, name: str) -> None: self.name = name - def content(self) -> NoReturn: + def content(self) -> None: """数据集的内容""" raise NotImplementedError @@ -30,7 +30,7 @@ class DataSet(object): class Image(DataSet): """继承自Data父类,假设这是一组图片数据""" - def content(self) -> NoReturn: + def content(self) -> None: """ 重载 图片数据集的内容 @@ -46,7 +46,7 @@ class Image(DataSet): class Text(DataSet): """同样继承自Data父类,假设这一组文字数据集""" - def content(self) -> NoReturn: + def content(self) -> None: """ 重载 文字数据集的内容 @@ -83,8 +83,8 @@ class AbstractDataFactory(object): return data_set -# 抽象工厂的核心思想:声明不同类型的工厂,生产出不同的类 def main(): + """抽象工厂的核心思想:通过通过同样的j声明不同类型的工厂,生产出不同的类""" # 声明了一个文字类的数据集工厂 factory = AbstractDataFactory(Text) # 给这个数据集起名 NLP -- Gitee From 35ee3b8131af2fd5dff0682a144a03ad0852b56c Mon Sep 17 00:00:00 2001 From: slgxmh Date: Sun, 27 Jun 2021 01:15:52 +0800 Subject: [PATCH 4/9] =?UTF-8?q?=E4=BC=98python=E5=8C=96=E5=B7=A5=E5=8E=82?= =?UTF-8?q?=E6=A8=A1=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- python/creational/factor.py | 51 ++++++++++++++++++++++++------------- 1 file changed, 34 insertions(+), 17 deletions(-) diff --git a/python/creational/factor.py b/python/creational/factor.py index b55f366..119c61b 100644 --- a/python/creational/factor.py +++ b/python/creational/factor.py @@ -1,27 +1,44 @@ -class TextLoader: +""" +工厂模式: +""" + + +class ImageDataA(object): + """数据集A的工厂类""" + def get_data(self) -> str: - return "This is a text!" + return "This is A!" + +class ImageDataB(object): + """数据集B的工厂类""" -class ImageLoader: def get_data(self) -> str: - return "This is a image!" + return "This is B!" -class DataLoaderFactory: - def get_loader(self, type: str = "Image") -> object: - """工厂方法""" - loaders = { - "Image": ImageLoader, - "Text": TextLoader, +class DatasetFactory(object): + def get_dataset(self, name: str) -> object: + """工厂方法的实现关键在于在于将需要用的类(本例中为数据集)集中管理起来,这里使用factories变量来注册所有的数据集 + + 参数: + name:不同数据集的名称 + """ + # 注册数据集的名称与对应的类 + factories = { + "A": ImageDataA, + "B": ImageDataB, } - return loaders[type]() + return factories[name]() + + +def main(): + """工厂模式的核心思想:""" + factory = DatasetFactory() + # 通过name参数分别加载A和B两个数据集 + A, B = factory.get_dataset(name="A"), factory.get_dataset(name="B") + print(A.get_data(), B.get_data()) # This is A! This is B! if __name__ == "__main__": - # 创建数据加载器工厂 - factory = DataLoaderFactory() - image, text = factory.get_loader( - type="Image"), factory.get_loader(type="Text") - # 输出加载的数据 - print(image.get_data(), text.get_data()) + main() -- Gitee From 9395329c58a9f4fbf8fae9b27489bdc0de83e3c2 Mon Sep 17 00:00:00 2001 From: slgxmh Date: Mon, 28 Jun 2021 16:47:04 +0800 Subject: [PATCH 5/9] =?UTF-8?q?=E4=BC=98=E5=8C=96python/=E5=B7=A5=E5=8E=82?= =?UTF-8?q?=E6=A8=A1=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- python/creational/factor.py | 55 +++++++++++++++++++++++++++---------- 1 file changed, 41 insertions(+), 14 deletions(-) diff --git a/python/creational/factor.py b/python/creational/factor.py index 119c61b..a7e53bd 100644 --- a/python/creational/factor.py +++ b/python/creational/factor.py @@ -1,24 +1,47 @@ """ 工厂模式: +类似工厂里通过流水线生产产品一样,工厂方法通过统一的接口(类比流水线)生产类(类比流水线生产的产品)。工厂模式的关键在于在创建类的时候并不需要明确的调用构造器而是通过工厂方法来创建需要的类。 + +本例: +假设本工程具具有多个模型,多个数据需要使用,我们在main()中通过同一个工厂方法来初始化不同的类。 """ -class ImageDataA(object): - """数据集A的工厂类""" +class ImageData(object): + """某个图像数据集""" def get_data(self) -> str: - return "This is A!" + """假设这是加载数据集的函数 + 返回:数据集 + """ + return "Images" -class ImageDataB(object): - """数据集B的工厂类""" - def get_data(self) -> str: - return "This is B!" +class ModelA(object): + """某个模型""" + + def get_model(self) -> str: + """假设这个方法可以得到模型 + + 返回:模型A + """ + return "ModelA" + + +class ModelB(object): + """另一个预训练模型""" + + def get_model(self) -> str: + """假设这个方法可以得到模型 + + 返回:模型B + """ + return "ModelB" class DatasetFactory(object): - def get_dataset(self, name: str) -> object: + def get(self, name: str) -> object: """工厂方法的实现关键在于在于将需要用的类(本例中为数据集)集中管理起来,这里使用factories变量来注册所有的数据集 参数: @@ -26,18 +49,22 @@ class DatasetFactory(object): """ # 注册数据集的名称与对应的类 factories = { - "A": ImageDataA, - "B": ImageDataB, + "DataSet": ImageData, + "A": ModelA, + "B": ModelB } return factories[name]() def main(): - """工厂模式的核心思想:""" + """工厂模式的核心思想:通过统一的接口创建类""" factory = DatasetFactory() - # 通过name参数分别加载A和B两个数据集 - A, B = factory.get_dataset(name="A"), factory.get_dataset(name="B") - print(A.get_data(), B.get_data()) # This is A! This is B! + # factory.get就是这个统一的接口 + data = factory.get("DataSet") + print(data.get_data()) + # 通过name参数分别加载A和B两个模型 + A, B = factory.get("A"), factory.get("B") + print(A.get_model(), B.get_model()) if __name__ == "__main__": -- Gitee From 02b368657740c46d5c1d641338db2661020de9cb Mon Sep 17 00:00:00 2001 From: slgxmh Date: Tue, 29 Jun 2021 10:25:57 +0800 Subject: [PATCH 6/9] =?UTF-8?q?=E4=BC=98=E5=8C=96python/abstract=5Ffactory?= =?UTF-8?q?.py=E7=9A=84=E6=8F=8F=E8=BF=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- python/creational/abstract_factor.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/python/creational/abstract_factor.py b/python/creational/abstract_factor.py index 8761623..b2ad273 100644 --- a/python/creational/abstract_factor.py +++ b/python/creational/abstract_factor.py @@ -28,7 +28,7 @@ class DataSet(object): class Image(DataSet): - """继承自Data父类,假设这是一组图片数据""" + """继承自DataSet父类,假设这是一组图片数据""" def content(self) -> None: """ @@ -44,7 +44,7 @@ class Image(DataSet): class Text(DataSet): - """同样继承自Data父类,假设这一组文字数据集""" + """同样继承自DataSet父类,假设这一组文字数据集""" def content(self) -> None: """ @@ -75,7 +75,7 @@ class AbstractDataFactory(object): """获得不同类型的数据 参数: - name: 数据集的名字 + name: 用户自定义数据集的名字 """ data_set = self.data_factory(name) @@ -87,16 +87,16 @@ def main(): """抽象工厂的核心思想:通过通过同样的j声明不同类型的工厂,生产出不同的类""" # 声明了一个文字类的数据集工厂 factory = AbstractDataFactory(Text) - # 给这个数据集起名 NLP + # 给这个数据集命名 NLP data_set = factory.get_data_set("NLP") # 查看 NLP 数据集的内容 - data_set.content() # Here is your data Text Text! + data_set.content() # Here is your data Text Text! # factor 变成了图像类的数据集工厂 factory = AbstractDataFactory(Image) - # 起名 CV 数据集 + # 获取一个数据集,命名为 CV 的数据集 data_set = factory.get_data_set("CV") # 查看 CV 数据集的内容 - data_set.content() # Here is your data Image Image! + data_set.content() # Here is your data Image Image! if __name__ == "__main__": -- Gitee From 01b6c747d7f1fe24fb773b995f0e62accbe8bcf4 Mon Sep 17 00:00:00 2001 From: slgxmh Date: Tue, 29 Jun 2021 14:41:27 +0800 Subject: [PATCH 7/9] =?UTF-8?q?=E4=BC=98=E5=8C=96REAMDME?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index ba5d4b9..78fcf5f 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,24 @@ # 写作角度 本人增删改查程序员出身,目前从事数据科学,看到一些数据科学从业者编程技能不足,同时也是为了提升自己的编程能力,顾计划站在数据科学的角度书写此书。 -# 适合人群 -已经熟悉Python基本语法及标准库,有简单的代码经验 + +# 前置知识 +* 了解Python基本语法,可以看懂基本的python代码 +* 有代码经验可以更好的体会到设计模式的用途,没有代码也可阅读在自己的项目中使用 + # 设计模式的作用 在制作软件的过程中,设计模式可能是新手最容易忽略的基础技能,软件(脚本)没有良好的结构,在升级演进的过程一定会浪费需要时间。相应的,如果在软件建立的过程中,拥有可维护、易拓展的良好结构,那么一定有利于后续的升级开发。 -# 写作结构 -每一种设计模式先用极简的语言介绍核心思想 -再结合数据科学的实际情况,给出简洁的Python语言的实现 -结合代码解释具体思路 -说明这种模式的应用场景 -给出应用该设计模式的实例 + +# 写作结 +1. 每一种设计模式先介绍核心思想 +1. 在设计模式实现的代码中,通过详细的代码注释来说明设计模式的思想与原理,使读者通过阅读代码就可以学习设计模式 +1. 在main()方法中的注释里,进行对数据模式的总结性称述 + +# 贡献指南 +* (强制)Python代码必须符合PEP8风格 +* (强制)每个设计模式单独为一个文件,并在文件头进行对此模式详细的说明 +* (强制)设计模式的实现必须以数据科学背景简单抽象情况举例 +* (强制)任何修改请向dev分支推送pull request +* (推荐)请优先共享Python的代码,但也接受任何代码但实现 + # 设计模式总结 -创建型的设计模式共有5种类型:工厂方法、抽象工厂、建造者、原型、单例 \ No newline at end of file +创建型的设计模式共有5种类型:工厂方法、抽象工厂、建造者、原型、单例模式 \ No newline at end of file -- Gitee From 72927d122788b4e2e55b6c776afb37f9676b6a74 Mon Sep 17 00:00:00 2001 From: slgxmh Date: Tue, 29 Jun 2021 17:07:21 +0800 Subject: [PATCH 8/9] =?UTF-8?q?=E4=BC=98=E5=8C=96factory.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- python/creational/{factor.py => factory.py} | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) rename python/creational/{factor.py => factory.py} (92%) diff --git a/python/creational/factor.py b/python/creational/factory.py similarity index 92% rename from python/creational/factor.py rename to python/creational/factory.py index a7e53bd..a8b9f01 100644 --- a/python/creational/factor.py +++ b/python/creational/factory.py @@ -41,7 +41,8 @@ class ModelB(object): class DatasetFactory(object): - def get(self, name: str) -> object: + @staticmethod + def get(name: str) -> object: """工厂方法的实现关键在于在于将需要用的类(本例中为数据集)集中管理起来,这里使用factories变量来注册所有的数据集 参数: @@ -58,12 +59,11 @@ class DatasetFactory(object): def main(): """工厂模式的核心思想:通过统一的接口创建类""" - factory = DatasetFactory() # factory.get就是这个统一的接口 - data = factory.get("DataSet") + data = DatasetFactory.get("DataSet") print(data.get_data()) # 通过name参数分别加载A和B两个模型 - A, B = factory.get("A"), factory.get("B") + A, B = DatasetFactory.get("A"), DatasetFactory.get("B") print(A.get_model(), B.get_model()) -- Gitee From bd31d6c17dc1212ffe792bf66ae0dbc772ffa24d Mon Sep 17 00:00:00 2001 From: slgxmh Date: Sun, 4 Jul 2021 22:18:30 +0800 Subject: [PATCH 9/9] =?UTF-8?q?=E4=BC=98=E5=8C=96=E8=A7=A3=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- python/creational/abstract_factor.py | 40 +++++++++++++--------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/python/creational/abstract_factor.py b/python/creational/abstract_factor.py index b2ad273..9d6ebe7 100644 --- a/python/creational/abstract_factor.py +++ b/python/creational/abstract_factor.py @@ -27,36 +27,34 @@ class DataSet(object): raise NotImplementedError -class Image(DataSet): +class DataSetA(DataSet): """继承自DataSet父类,假设这是一组图片数据""" def content(self) -> None: """ 重载 - 图片数据集的内容 - 返回:假设返回了一组图片 + 返回:数据集A """ - print("Image!") + print("A!") def __str__(self) -> str: - return f"Image<{self.name}>" + return f"A<{self.name}>" -class Text(DataSet): +class DataSetB(DataSet): """同样继承自DataSet父类,假设这一组文字数据集""" def content(self) -> None: """ 重载 - 文字数据集的内容 - 返回:假设返回了一组字符 + 返回:数据集B """ - print("Text!") + print("B!") def __str__(self) -> str: - return f"Text<{self.name}>" + return f"B<{self.name}>" class AbstractDataFactory(object): @@ -86,17 +84,17 @@ class AbstractDataFactory(object): def main(): """抽象工厂的核心思想:通过通过同样的j声明不同类型的工厂,生产出不同的类""" # 声明了一个文字类的数据集工厂 - factory = AbstractDataFactory(Text) - # 给这个数据集命名 NLP - data_set = factory.get_data_set("NLP") - # 查看 NLP 数据集的内容 - data_set.content() # Here is your data Text Text! - # factor 变成了图像类的数据集工厂 - factory = AbstractDataFactory(Image) - # 获取一个数据集,命名为 CV 的数据集 - data_set = factory.get_data_set("CV") - # 查看 CV 数据集的内容 - data_set.content() # Here is your data Image Image! + factory = AbstractDataFactory(DataSetA) + # 给这个数据集命名为public_dataset + data_set = factory.get_data_set("public_dataset") + # 调用了DataSetA的content()方法 + data_set.content() # A! + # factor变成了图像类的数据集工厂 + factory = AbstractDataFactory(DataSetB) + # 给这个数据集命名为private_dataset + data_set = factory.get_data_set("private_dataset") + # 调用了DatasetB类content()方法 + data_set.content() # B! if __name__ == "__main__": -- Gitee