适合纯文科生的 python 100个知识点 实践 二

194 阅读11分钟

本文源自白璽,创自白璽。转载请标注出处。本文参与掘金日新计划【博客搬家】

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文档的步骤:

  1. 安装MkDocs

在命令行中执行以下命令,安装MkDocs:

pip install mkdocs
  1. 创建文档项目

在命令行中执行以下命令,创建一个新的MkDocs项目:

mkdocs new myproject

其中,myproject是项目名称,可以根据需要进行修改。执行该命令后,会在当前目录下创建一个名为myproject的文件夹,其中包含了一个默认的文档配置文件mkdocs.yml和一个空的docs文件夹。

  1. 编写文档

在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.
  1. 配置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文件。

  1. 生成文档

在命令行中执行以下命令,生成文档网站:

mkdocs build

执行该命令后,会在当前目录下创建一个名为site的文件夹,其中包含了生成的HTML网站。

  1. 预览文档

在命令行中执行以下命令,预览生成的文档网站:

mkdocs serve

执行该命令后,会启动一个本地服务器,可以通过浏览器访问生成的文档网站。例如,可以在浏览器中访问http://localhost:8000,查看生成的文档。

总的来说,MkDocs是一个简单易用的文档生成工具,使用Markdown语言编写文档,并将其转换成漂亮的HTML网站。如果需要更加定制化的文档生成,可以考虑使用Sphinx等工具。

本文是结合ChatGPT的答案总结的知识点,有不足之处请大佬们给出反馈。