本文源自白璽,创自白璽。转载请标注出处。本文参与掘金日新计划【博客搬家】
Python高级语法
31 面向对象设计模式
31.1 面向对象设计模式的定义
面向对象设计模式是一种通用的解决问题的方法,它提供了一些设计方案,可以用于解决特定类型的问题。以下是常见的面向对象设计模式及其相应的示例代码:
31.2 工厂模式
工厂模式是一种创建对象的模式,它使用工厂方法来处理创建对象的过程。
示例代码:
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
pass
class Dog(Animal):
def speak(self):
return "Woof!"
class Cat(Animal):
def speak(self):
return "Meow!"
class AnimalFactory:
def create_animal(self, animal_type, name):
if animal_type == 'dog':
return Dog(name)
elif animal_type == 'cat':
return Cat(name)
else:
return None
31.3 单例模式
单例模式是一种保证只有一个实例被创建的模式。
示例代码:
class Singleton:
__instance = None
def __init__(self):
if Singleton.__instance != None:
raise Exception("You cannot create more than one instance.")
else:
Singleton.__instance = self
@staticmethod
def get_instance():
if Singleton.__instance == None:
Singleton()
return Singleton.__instance
31.4 装饰器模式
装饰器模式是一种在运行时添加新功能的模式,它使用装饰器来修改对象的行为。
示例代码:
class Component:
def operation(self):
pass
class ConcreteComponent(Component):
def operation(self):
return "ConcreteComponent"
class Decorator(Component):
_component = None
def __init__(self, component):
self._component = component
def operation(self):
pass
class ConcreteDecoratorA(Decorator):
def operation(self):
return f"ConcreteDecoratorA({self._component.operation()})"
class ConcreteDecoratorB(Decorator):
def operation(self):
return f"ConcreteDecoratorB({self._component.operation()})"
31.5 观察者模式
观察者模式是一种在对象之间定义一对多的依赖关系的模式,它使得当一个对象状态改变时,所有依赖它的对象都会被通知并自动更新。
示例代码:
class Observer:
def update(self, subject):
pass
class Subject:
_observers = []
def attach(self, observer):
self._observers.append(observer)
def detach(self, observer):
self._observers.remove(observer)
def notify(self):
for observer in self._observers:
observer.update(self)
class ConcreteSubject(Subject):
_state = None
def get_state(self):
return self._state
def set_state(self, state):
self._state = state
self.notify()
class ConcreteObserverA(Observer):
def update(self, subject):
print(f"ConcreteObserverA: {subject.get_state()}")
class ConcreteObserverB(Observer):
def update(self, subject):
print(f"ConcreteObserverB: {subject.get_state()}")
31.6 策略模式
定义一系列算法并将其封装起来,使它们可以相互替换的模式。
示例代码:
class Strategy:
def do_operation(self, num1, num2):
pass
class OperationAdd(Strategy):
def do_operation(self, num1, num2):
return num1 + num2
class OperationSubtract(Strategy):
def do_operation(self, num1, num2):
return num1 - num2
class OperationMultiply(Strategy):
def do_operation(self, num1, num2):
return num1 * num2
class Context:
_strategy = None
def __init__(self, strategy):
self._strategy = strategy
def execute_strategy(self, num1, num2):
return self._strategy.do_operation(num1, num2)
31.7 访问者模式
访问者模式是一种在不改变已有类的情况下,向已有类添加新功能的模式。
示例代码:
class ComputerPart:
def accept(self, visitor):
pass
class Keyboard(ComputerPart):
def accept(self, visitor):
visitor.visit_keyboard(self)
class Monitor(ComputerPart):
def accept(self, visitor):
visitor.visit_monitor(self)
class Mouse(ComputerPart):
def accept(self, visitor):
visitor.visit_mouse(self)
class ComputerPartVisitor:
def visit_keyboard(self, keyboard):
pass
def visit_monitor(self, monitor):
pass
def visit_mouse(self, mouse):
pass
class ComputerPartDisplayVisitor(ComputerPartVisitor):
def visit_keyboard(self, keyboard):
print("Displaying keyboard.")
def visit_monitor(self, monitor):
print("Displaying monitor.")
def visit_mouse(self, mouse):
print("Displaying mouse.")
31.8 命令模式
命令模式是一种将请求封装为对象,从而使您可以使用不同的请求、队列或日志来参数化其他对象的模式。
示例代码:
class Command:
def execute(self):
pass
class Light:
def on(self):
print("Light is on.")
def off(self):
print("Light is off.")
class LightOnCommand(Command):
_light = None
def __init__(self, light):
self._light = light
def execute(self):
self._light.on()
class LightOffCommand(Command):
_light = None
def __init__(self, light):
self._light = light
def execute(self):
self._light.off()
class SimpleRemoteControl:
_slot = None
def set_command(self, command):
self._slot = command
def button_was_pressed(self):
self._slot.execute()
以上是常见的面向对象设计模式及其相应的示例代码。这些模式在实际开发中经常被使用,可以帮助程序员提高开发效率和代码质量。
32 单元测试
32.1 单元测试的定义
单元测试是一种软件测试方法,用于测试代码中的最小可测试单元,通常是函数或方法。单元测试通常会针对每个函数或方法编写多个测试用例,以确保代码的正确性和稳定性。
32.2 单元测试代码示例
import unittest
# 要测试的函数
def add(a, b):
return a + b
# 编写测试用例
class TestAdd(unittest.TestCase):
def test_add_positive_numbers(self):
self.assertEqual(add(2, 3), 5)
def test_add_negative_numbers(self):
self.assertEqual(add(-2, -3), -5)
def test_add_zero(self):
self.assertEqual(add(0, 0), 0)
def test_add_float_numbers(self):
self.assertAlmostEqual(add(0.1, 0.2), 0.3, places=2)
def test_add_string(self):
with self.assertRaises(TypeError):
add('hello', 'world')
# 运行测试用例
if __name__ == '__main__':
unittest.main()
在这个示例中,我们编写了一个简单的函数add,它将两个数字相加。然后,我们编写了一个名为TestAdd的测试用例类,并定义了多个测试用例函数来测试add函数的不同方面。最后,我们使用unittest.main()函数来运行测试用例。
以上测试用例中,test_add_positive_numbers测试了两个正整数的加法结果是否正确,test_add_negative_numbers测试了两个负整数的加法结果是否正确,test_add_zero测试了零加零的结果是否正确,test_add_float_numbers测试了两个浮点数的加法结果是否正确,test_add_string测试了传入非数字参数时函数是否能够正确地抛出异常。
这个例子演示了如何使用Python的内置unittest模块来编写单元测试用例。通过编写测试用例,我们可以确保代码的正确性和稳定性,使我们的代码更加健壮和可靠。
33集成测试
33.1 集成测试的定义
集成测试是一种测试方法,用于测试多个组件或模块在一起运行时的行为。它可以测试整个系统的功能、性能和稳定性。在Python中,可以使用unittest模块来进行集成测试。
33.2 集成测试的的示例
pythonCopy code
import unittest
from my_app import app, db
class TestMyApp(unittest.TestCase):
def setUp(self):
self.app = app.test_client()
db.create_all()
def tearDown(self):
db.session.remove()
db.drop_all()
def test_index(self):
response = self.app.get('/')
self.assertEqual(response.status_code, 200)
def test_login(self):
response = self.app.post('/login', data=dict(
username='admin',
password='password'
), follow_redirects=True)
self.assertIn(b'Welcome admin!', response.data)
if __name__ == '__main__':
unittest.main()
在这个例子中,我们定义了一个TestMyApp类,它继承自unittest.TestCase类。setUp()方法在每个测试方法之前执行,用于设置测试环境。tearDown()方法在每个测试方法之后执行,用于清理测试环境。test_index()和test_login()方法是实际的测试方法,它们使用测试客户端来模拟HTTP请求,并检查响应是否符合预期。
此外,我们在if name == 'main'语句中调用unittest.main()函数来运行测试。这将自动查找并运行所有以test_开头的方法。
这是一个简单的例子,真实的集成测试可能涉及更多的组件和复杂的测试场景。但是,使用unittest模块可以轻松地编写和运行集成测试,并检查系统的整体行为。
34 生成文档
34.1 生成文档的定义
在Python中,可以使用多个工具生成文档,比如Sphinx、pydoc、pdoc等。
34.2 Sphinx
首先,需要安装Sphinx:
pip install sphinx
接下来,创建一个Sphinx项目:
sphinx-quickstart
执行该命令后,会生成一个Sphinx项目的基本结构,包括配置文件和目录结构等。其中,配置文件conf.py中可以设置生成文档的参数,比如文档语言、文档格式、主题等。
在Sphinx项目的source目录下,可以创建.rst文件编写文档。
.. HelloWorld文档主文件,由sphinx-quickstart
在Tue Mar 30 2023 15:40:13 GMT-0700 (Pacific Daylight Time)创建。
你可以完全按照你的喜好调整这个文件,但它至少应该包含根`toctree`指令。
HelloWorld ==========
.toctree:: :maxdepth: 2 :caption:内容:
介绍 使用方法
介绍 ------------
这就是介绍。
使用方法 -----
这是用法。
其中,第一行表示该文档是由Sphinx生成的。第2行至第5行是注释,可以设置一些基本信息。第7行至第13行是文档的正文,使用了reStructuredText格式编写。其中,第9行的toctree指令表示该文档的目录结构,可以包含多个.rst文件,每个文件对应一个章节。
运行以下命令生成文档:
make html
执行该命令后,在Sphinx项目的_build目录下会生成HTML格式的文档。打开index.html文件即可查看文档。
此外,Sphinx还支持生成其他格式的文档,比如PDF、EPUB等。可以在配置文件conf.py中设置输出格式,如下所示:
# -- Options for output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
# html_theme = 'alabaster'
#
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
#
# html_logo = '_static/logo.png'
#
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
#
# html_show_sphinx = True
#
# Output file base name for HTML help builder.
htmlhelp_basename = 'HelloWorlddoc'
# -- Options for LaTeX output ---------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#
# 'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#
# 'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#
# 'preamble': '',
# Latex figure (float) alignment
#
# 'figure_align': 'htbp',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
(master_doc, 'HelloWorld.tex', 'HelloWorld Documentation',
'Your Name', 'manual'),
]
# -- Options for EPUB output ----------------------------------------------
# Bibliographic Dublin Core info.
epub_title = project
epub_author = author
epub_publisher = publisher
epub_identifier = 'urn:isbn:978-xxx-xxx-xxx-x'
epub_scheme = 'ISBN'
epub_uid = 'unique_id'
epub_cover = ('_static/cover.png', 'epub-cover.html')
epub_language = 'en'
epub_exclude_files = ['search.html']
# The depth of the table of contents in toc.ncx.
epub_tocdepth = 3
# Allow duplicate toc entries.
epub_tocdup = True
以上代码中,设置了LaTeX和EPUB输出的参数,可以生成对应的文档格式。
总的来说,使用Sphinx生成文档需要编写reStructuredText格式的文档内容,设置一些基本参数和格式,然后运行相应的命令即可生成文档。Sphinx支持定制化程度较高,可以根据具体需要进行调整。
34.3 pydoc
pydoc是Python自带的文档生成工具,可以直接从Python代码中生成文档。以下是一个示例:
首先,需要在Python代码中添加文档注释,如下所示:
def add(x, y):
"""
This function adds two numbers.
:param x: The first number.
:type x: int
:param y: The second number.
:type y: int
:return: The sum of x and y.
:rtype: int
"""
return x + y
其中,文档注释使用了reStructuredText格式编写,可以描述函数的参数、返回值等信息。
接下来,可以在命令行中使用pydoc命令生成文档,如下所示:
pydoc -w mymodule
其中,mymodule是要生成文档的Python模块名称。执行该命令后,会在当前目录下生成一个HTML文件,包含了该模块中的所有函数和类的文档。打开该文件即可查看文档。
除了pydoc,还可以使用pdoc生成Python文档。pdoc是一个第三方工具,需要先安装:
pip install pdoc3
安装完成后,可以在命令行中使用pdoc命令生成文档,如下所示:
pdoc --html mymodule
执行该命令后,会在当前目录下生成一个HTML文件夹,包含了该模块中的所有函数和类的文档。打开index.html文件即可查看文档。
总的来说,生成Python文档的过程主要包括添加文档注释、选择文档生成工具、执行相应命令等步骤。可以根据具体情况选择合适的工具和方式进行文档生成。
34.4 MkDocs
MkDocs是一种简单易用的文档生成工具,它使用Markdown语言编写文档,并将其转换成漂亮的HTML网站。以下是如何使用MkDocs生成Python文档的步骤:
- 安装MkDocs
在命令行中执行以下命令,安装MkDocs:
pip install mkdocs
- 创建文档项目
在命令行中执行以下命令,创建一个新的MkDocs项目:
mkdocs new myproject
其中,myproject是项目名称,可以根据需要进行修改。执行该命令后,会在当前目录下创建一个名为myproject的文件夹,其中包含了一个默认的文档配置文件mkdocs.yml和一个空的docs文件夹。
- 编写文档
在docs文件夹中,可以创建一个或多个Markdown文件,用于编写文档内容。例如,可以创建一个名为getting-started.md的文件,并在其中添加以下内容:
# Getting Started
Welcome to my Python project! Here are some instructions to get you started:
1. First, install the project dependencies by running `pip install -r requirements.txt`.
2. Next, run the main script with the command `python main.py`.
3. That's it! You're now up and running.
- 配置MkDocs
编辑mkdocs.yml文件,配置MkDocs生成文档的设置。例如,可以添加以下内容:
site_name: My Python Project
theme: readthedocs
nav:
- Home: index.md
- Getting Started: getting-started.md
其中,site_name用于设置文档网站的名称,theme用于设置文档网站的主题,nav用于设置文档网站的导航栏。在nav中,可以添加需要显示的Markdown文件。
- 生成文档
在命令行中执行以下命令,生成文档网站:
mkdocs build
执行该命令后,会在当前目录下创建一个名为site的文件夹,其中包含了生成的HTML网站。
- 预览文档
在命令行中执行以下命令,预览生成的文档网站:
mkdocs serve
执行该命令后,会启动一个本地服务器,可以通过浏览器访问生成的文档网站。例如,可以在浏览器中访问http://localhost:8000,查看生成的文档。
总的来说,MkDocs是一个简单易用的文档生成工具,使用Markdown语言编写文档,并将其转换成漂亮的HTML网站。如果需要更加定制化的文档生成,可以考虑使用Sphinx等工具。
本文是结合ChatGPT的答案总结的知识点,有不足之处请大佬们给出反馈。