Python异常处理:12个异常处理技巧,你掌握了几个?

news2024/11/13 11:19:06

探索Python异常处理的深度策略,从基础的try-except结构到自定义异常类的创建,再到利用上下文管理器和装饰器提升代码健壮性。深入理解异常传递机制,掌握日志记录与并发环境下异常处理的关键实践,强调了性能考量与避免异常作为控制流程的重要性。本系列概述了实现精准异常管理的全方位技巧,助力开发者构建稳定、高效的Python应用程序。
<文末附带精品籽料!>

CSDN大礼包:《2024年最新全套学习资料包》免费分享

1、基础捕获:try-except块

在Python异常处理中,try-except块是最基础也是最核心的构造,它允许开发者优雅地应对程序运行时可能遇到的错误情况。通过合理地使用这一机制,可以增强代码的健壮性,提升用户体验。

1.1 简单异常捕获

当预期某段代码可能引发异常时,将其包裹在try块内 ,然后使用一个或多个except子句来捕获并处理这些异常。例如,处理文件读取错误:

try:
    with open('example.txt', 'r') as file:
        content = file.read()
except FileNotFoundError:
    print("文件未找到 ,请检查路径是否正确。")

这段代码尝试读取example.txt文件,如果文件不存在,则捕获FileNotFoundError并提示用户。

1.2 多异常处理

有时 ,一段代码可能会抛出多种类型的异常 ,这时可以使用一个except块来同时捕获多个异常类型 ,或者使用多个except块分别处理不同异常:

try:
    # 假设这里执行的代码可能抛出多种类型的异常
    result = 10 / 0
except (ZeroDivisionError, TypeError) as e:
    print(f"发生错误: {e}")

此例中 ,无论是除以零还是类型错误 ,都会被捕获并打印出错误信息。

1.3 异常链抛出

在处理异常时,可能需要保留原始异常信息的同时,添加额外的上下文或重新抛出异常。使用raise from语法可以达到这一目的:

try:
    open('nonexistent.txt')
except FileNotFoundError as fnf_error:
    raise ValueError("配置文件缺失") from fnf_error

在这个例子中,即使我们重新抛出了一个ValueError,原始的FileNotFoundError也会被记录下来,便于调试。

通过上述方法 ,开发者能够构建出更加健壮、易于维护的Python应用程序,有效应对运行时可能出现的各种异常情况。

2、高级技巧:上下文管理器 with 💼

在Python中,with语句结合上下文管理器提供了自动资源管理和代码块执行控制的强大能力,显著提升了代码的整洁度和健壮性。

2.1 自动资源管理

上下文管理器通过定义__enter____exit__方法,使得在with语句块中操作资源时,无论是否发生异常,都能确保资源被正确地初始化和清理。以下是一个简单的文件操作示例:

class ManagedFile:
    def __init__(self, filename):
        self.filename = filename

    def __enter__(self):
        self.file = open(self.filename, 'r')
        return self.file

    def __exit__(self, exc_type, exc_val, exc_tb):
        if self.file:
            self.file.close()

# 使用自定义上下文管理器
with ManagedFile('example.txt') as file:
    content = file.read()
    print(content)

在这个例子中,ManagedFile类作为一个上下文管理器,确保了example.txt文件会被自动打开并在操作完成后关闭,即使过程中出现异常也是如此。

2.2 定制上下文管理器

除了管理文件外,with语句还能应用于数据库连接、锁、网络连接等众多资源管理场景。通过定义自己的上下文管理器类 ,可以实现高度定制化的资源控制逻辑。以下是一个模拟数据库连接的简单上下文管理器示例:

class DatabaseConnection:
    def __init__(self, db_name):
        self.db_name = db_name
        self.connection = None

    def __enter__(self):
        print("连接数据库:", self.db_name)
        # 模拟建立数据库连接
        self.connection = "数据库连接成功"
        return self.connection

    def __exit__(self, exc_type, exc_val, exc_tb):
        if self.connection:
            print("关闭数据库连接:", self.db_name)
            # 模拟关闭数据库连接
            self.connection = None

# 使用自定义数据库连接上下文管理器
with DatabaseConnection('my_database') as conn:
    print("执行数据库操作...")

通过上述例子,我们可以看到 ,定制的上下文管理器让资源管理变得更加简洁且安全,避免了手动处理资源打开和关闭带来的潜在错误,是Python异常处理和资源管理中的高级而实用的技巧。

3、捕获特定异常:else & finally块 🎯

在Python异常处理结构中,elsefinally块提供了对程序流更细致的控制,增强了异常处理的灵活性和完整性。

3.1 else块的妙用

else子句与try-except结构配合使用,用于在没有异常发生的情况下执行代码块。这意味着,如果try部分的代码成功执行(即没有触发任何异常),则直接跳过所有except子句,执行else块内的代码。这种方式可以清晰地区分正常流程与异常处理逻辑,提高代码可读性。

try:
    result = 10 / 2
except ZeroDivisionError:
    print("发生了除以零的错误")
else:
    print("运算成功,结果是:", result)

在这个例子中 ,由于除数不是零 ,else块将被执行,输出“运算成功 ,结果是: 5.0”。

3.2 finally确保代码执行

finally块无论是否发生异常 ,甚至是try块中有returnbreak等改变控制流的语句,都会保证其内部的代码被执行。这对于释放资源、关闭文件或数据库连接等清理工作尤为重要。

try:
    num = int(input("请输入一个数字: "))
    print("输入的数字是:", num)
except ValueError:
    print("输入错误,请输入一个整数。")
finally:
    print("这是finally块 ,总是会被执行。")

无论用户输入是否合法 ,最后都会输出“这是finally块 ,总是会被执行。”,确保了必要的清理操作得以完成。

通过合理利用elsefinally块,不仅可以让异常处理逻辑更加清晰和高效,还能确保关键的清理工作不被遗漏 ,提升代码的健壮性和维护性。

4、自定义异常类:精准控制错误信息 🏗️

在复杂的软件系统中,标准的异常类型可能无法精确描述所有可能遇到的错误情况。通过自定义异常类,可以提供更具体的错误信息,便于调试和问题定位。Python允许开发者继承自Exception基类来创建自定义异常。

4.1 继承Exception基类

创建自定义异常的基本步骤是定义一个新的类,该类直接或间接继承自Exception类。下面是一个简单的例子,定义了一个CustomError异常类:

class CustomError(Exception):
    """自定义的基础异常类"""
    pass

# 抛出自定义异常
def divide_by_zero():
    try:
        x = 1 / 0
    except ZeroDivisionError:
        raise CustomError("尝试进行了除零操作")

try:
    divide_by_zero()
except CustomError as e:
    print(e)

当尝试除以零时,会捕获到内置的ZeroDivisionError,然后重新抛出CustomError ,输出自定义的错误信息:“尝试进行了除零操作”。

4.2 添加自定义属性

为了提供更丰富的错误信息 ,可以在自定义异常类中添加属性。这样,在处理异常时 ,可以获得更多的上下文信息。下面的示例展示了如何添加额外的详情:

class CustomErrorWithDetails(CustomError):
    def __init__(self, message, detail=None):
        super().__init__(message)
        self.detail = detail

def process_data(data):
    if not data:
        raise CustomErrorWithDetails("数据为空", detail="缺少必要的输入数据")

try:
    process_data([])
except CustomErrorWithDetails as e:
    print(f"错误信息: {e}, 详细信息: {e.detail}")

在这个例子中,当调用process_data函数传入空列表时,会抛出CustomErrorWithDetails异常,输出包括基本错误信息及附加的详细信息:“错误信息: 数据为空, 详细信息: 缺少必要的输入数据”。

通过自定义异常类 ,开发者能够更精确地控制程序中错误信息的表达,使得错误报告更为详尽且易于理解,从而加速问题排查过程。

5、使用raise:主动抛出异常 🔥

在Python中,raise语句允许开发者主动抛出异常,这对于控制程序流程、验证条件以及增强错误报告非常有用。通过精确地在代码中指定异常抛出点,可以提高程序的健壮性和可维护性。

5.1 条件抛出异常

在某些条件下,如果不符合预期,开发者可以通过raise手动抛出异常。这常用于输入验证、状态检查等场景。例如,检查函数参数的有效性:

def calculate_square_root(n):
    if n < 0:
        raise ValueError("负数没有平方根")
    return n ** 0.5

try:
    print(calculate_square_root(-4))
except ValueError as e:
    print(e)  # 输出: 负数没有平方根

上述代码中,如果尝试计算负数的平方根,会抛出ValueError异常并附带说明信息。

5.2 重新抛出异常带额外信息

在异常处理流程中 ,有时需要在捕获一个异常后,根据情况重新抛出另一个异常 ,或者在原异常基础上添加更多信息后再抛出。这可以通过在except块中使用raise语句实现 ,可选地传入原有异常实例以保持堆栈跟踪。

def process_data(data):
    try:
        # 假设这里执行的逻辑可能抛出多种异常
        ...
    except Exception as original_exception:
        raise DataProcessingError("数据处理失败") from original_exception

class DataProcessingError(Exception):
    pass

try:
    process_data(None)
except DataProcessingError as e:
    print(e)  # 输出: 数据处理失败

这里 ,如果process_data函数内部的逻辑遇到错误,会捕获原始异常,然后抛出一个更具针对性的DataProcessingError ,同时保留原始异常的追踪信息,有助于调试。

通过上述方法,raise语句不仅能够灵活地控制程序的异常流程,还能在异常传播过程中增强错误信息的丰富性和准确性,是异常处理策略中的重要组成部分。

6、异常传递:理解Python异常机制 🔄

Python的异常处理机制支持异常在函数调用栈中的向上抛出与捕获,这一特性对于构建复杂应用的健壮性至关重要。

6.1 函数调用栈中的异常

当函数内部抛出异常而未被捕获时 ,异常会向上传递至调用该函数的上一层,这一过程会沿着调用栈逐级回溯 ,直至遇到合适的except块捕获该异常,或最终未被捕获导致程序终止。理解这一过程对于调试和设计异常处理逻辑非常重要。

def inner_function():
    raise ValueError("内部错误")

def outer_function():
    inner_function()

try:
    outer_function()
except ValueError as e:
    print("捕获到异常:", e)  # 输出: 捕获到异常: 内部错误

在这个例子中,尽管ValueError是在inner_function内部产生的,但通过try-except结构在外层的outer_function调用中被捕获,体现了异常的传递与捕获机制。

6.2 try内函数的异常处理

当在一个try块内部调用其他函数时,这些函数内发生的异常同样遵循上述传递规则。但值得注意的是,try块只捕获在其直接作用域内发生的异常。若内部函数有独立的异常处理逻辑,这将不会影响外部try块的捕获行为。

def may_raise_exception(value):
    if value == 0:
        raise ValueError("值不能为0")

def wrapper_function(value):
    try:
        may_raise_exception(value)
    except ValueError as ve:
        print(f"处理了内部异常: {ve}")

wrapper_function(0)  # 输出: 处理了内部异常: 值不能为0

这里,虽然may_raise_exceptionwrapper_functiontry块内被调用,但因为异常被立即捕获并处理,所以不会进一步向外传播。

深入理解异常的传递与处理机制,可以帮助开发者更好地设计程序结构 ,确保异常得到妥善处理,提升程序的稳定性和健壮性。

7、日志记录:logging模块的重要性 📝

在Python应用开发中,合理利用logging模块记录日志信息是监控程序运行状态、诊断问题的关键实践。通过精细的日志管理,可以大幅提升系统的可维护性和故障排查效率。

7.1 配置日志级别

logging模块支持设置不同的日志级别 ,以控制哪些信息会被记录。常见的日志级别从低到高包括DEBUGINFOWARNINGERRORCRITICAL。开发者可以根据实际需求调整日志级别 ,过滤不必要的日志输出。

import logging

# 配置日志级别为WARNING,低于这个级别的日志将不会被记录
logging.basicConfig(level=logging.WARNING)

logging.debug("这是一条DEBUG信息")
logging.info("这是一条INFO信息")
logging.warning("这是一条WARNING信息")

执行上述代码,仅“这是一条WARNING信息”会被打印出来,因为日志级别设置为了WARNING及以上。

7.2 异常时自动记录日志

结合异常处理与日志记录,可以在异常发生时自动记录详细的错误信息 ,这对于追踪和分析问题原因至关重要。通过在except块内使用logging.error或更高级别的方法记录异常,可以确保异常情况被完整记录。

def divide(a, b):
    try:
        result = a / b
    except ZeroDivisionError:
        logging.error("尝试除以零", exc_info=True)
    else:
        print(f"结果是: {result}")

divide(10, 0)

当尝试除以零时,logging.error不仅会记录下错误信息“尝试除以零”,还会通过exc_info=True参数自动包含异常堆栈跟踪信息 ,极大地便利了事后分析。

通过上述实践,可以清晰地看到 ,logging模块不仅是监控应用健康状态的窗口 ,也是异常处理机制中不可或缺的一部分 ,对于保障程序长期稳定运行具有不可估量的价值。

8、跨模块异常处理:最佳实践 🌐

在大型项目或涉及多模块的Python应用中,统一和规范地处理异常尤为关键。跨模块的异常处理策略能增强代码的可维护性和稳定性,确保错误信息的一致性和准确性。

8.1 公共异常处理策略

统一异常基类:定义项目级别的基础异常类,所有自定义异常都应从此基类派生。这样可以方便地通过捕获这个基类来处理项目中的所有异常,同时也便于识别异常的来源。

class MyAppError(Exception):
    """项目基础异常类"""

class DataFetchError(MyAppError):
    """数据获取异常"""

集中处理模式:在应用的主入口或模块接口处设置统一的异常捕获逻辑 ,处理并记录异常,而不是在每个函数内部都进行详尽的异常处理。这样可以简化代码 ,降低模块间的耦合度。

def main():
    try:
        # 调用各个模块的功能
        module_a.function_a()
        module_b.function_b()
    except MyAppError as e:
        log_exception(e)
        handle_error_gracefully(e)

8.2 异常封装与传播

异常封装:在模块内部处理异常时,如果需要向上层报告异常,应该考虑是否需要对异常进行封装。这通常意味着捕获原始异常,然后抛出一个新的异常,同时将原始异常作为新异常的原因(通过from关键字)。

def fetch_data_from_api(url):
    try:
        response = requests.get(url)
        response.raise_for_status()  # 抛出HTTP错误
    except requests.RequestException as re:
        raise DataFetchError("API请求失败") from re

有意义的异常传播:决定何时捕获并处理异常,何时让异常继续向上抛出,是一项重要的决策。原则是,越靠近能够理解和处理异常的层级 ,越应该捕获异常。如果当前层级无法妥善处理异常,应让其自然传播,直到找到合适的处理位置。

def process_data(data):
    if not data:
        raise DataProcessError("缺少数据,无法继续处理")
    # ...处理逻辑...

采用上述策略,跨模块的异常处理不仅能够保证错误信息的清晰传递,还能促进代码的模块化和解耦,为项目的长期维护和扩展打下坚实的基础。

9、使用assert断言:调试中的异常检查 🔍

在Python程序开发和调试阶段,assert语句是一种强大的工具 ,用于在代码中插入检查点,确保变量或表达式的预期状态。正确使用assert能够帮助开发者提前发现逻辑错误 ,提升代码质量。

9.1 断言的正确使用场景

assert主要适用于开发和测试环境中,用来验证不应该发生的错误条件。以下是一些典型的使用场景:

  • 不变量检查:确保程序中的某些状态或变量值在执行过程中的某个点满足预设条件。

    def increment_counter(counter):
    assert counter >= 0, "Counter should not be negative"
    counter += 1
    return counter
    
  • 函数前提条件验证:在函数开始时检查输入参数的有效性。

    def divide(a, b):
    assert b != 0, "Divisor cannot be zero"
    return a / b
    
  • 调试辅助:在复杂的逻辑分支中 ,确认程序按预期路径执行。

def complex_logic(flag):
   assert flag in [True, False], "Flag must be boolean"
   if flag:
       # ...执行逻辑A...
   else:
       # ...执行逻辑B...

9.2 断言与异常的区别

尽管assert在遇到失败时会引发AssertionError,但它与直接使用if语句抛出异常有本质区别:

  • 启用与禁用:通过 -O-OO 命令行选项运行Python程序时,所有assert语句将被忽略,这使得生产环境中的性能影响最小。而显式抛出的异常不会受此影响。

  • 意图表达assert主要用于自我检查,表达开发者对代码状态的期望。异常处理则更多关注于程序中可能遇到的外部或内部错误 ,并提供恢复机制。

  • 调试信息assert失败时 ,会提供失败的表达式和所在位置的信息 ,这对于调试非常有帮助。而自定义异常可以携带更丰富的上下文信息,适合对外部用户或下游代码解释错误原因。

综上所述,assert断言是Python中一种强大的调试辅助工具,它有助于在开发阶段捕捉逻辑错误,但应当谨慎使用,避免在生产环境中依赖它来进行错误处理。

10、并发编程中的异常处理:asyncio 示例 ⚡

在使用asyncio进行并发编程时,异常处理机制与同步编程有所不同 ,因为异步任务可能在事件循环的不同阶段抛出异常。合理处理这些异常对于编写健壮的异步应用至关重要。

10.1 异步函数中的try-except

尽管try-except结构在异步函数中同样适用,但需要注意的是,异常处理逻辑也需适应异步上下文。例如,当在异步函数中执行可能导致异常的操作时:

import asyncio

async def divide_async(a, b):
    try:
        await asyncio.sleep(0.1)  # 模拟异步操作
        return a / b
    except ZeroDivisionError:
        print("尝试除以零")
        return None

async def main():
    result = await divide_async(10, 0)
    print(f"结果是: {result}")

asyncio.run(main())

在此例中,即使divide_async函数是异步的,异常处理依然能够正常工作,捕获到ZeroDivisionError

10.2 任务取消与异常传递

asyncio中,任务取消是一种常见的控制流机制,与异常处理紧密相关。当一个任务被取消时 ,它会抛出CancelledError异常。正确处理任务取消和异常传递是维持程序稳定性的关键。

async def task_with_cancellation():
    try:
        while True:
            await asyncio.sleep(1)
            print("任务执行中...")
            if asyncio.current_task().cancelled():
                raise asyncio.CancelledError("任务被取消")
    except asyncio.CancelledError:
        print("任务已响应取消请求")

async def cancel_task_after_delay(task):
    await asyncio.sleep(3)
    task.cancel()
    print("已请求取消任务")

async def main():
    task = asyncio.create_task(task_with_cancellation())
    asyncio.create_task(cancel_task_after_delay(task))
    await asyncio.gather(task, return_exceptions=True)  # 允许gather收集异常

asyncio.run(main())

这个例子展示了如何在异步任务中响应取消请求,并且在任务被取消时,异常被适当处理。使用asyncio.gather时 ,通过return_exceptions=True参数,可以收集到任务中抛出的所有异常 ,包括因取消而引发的CancelledError,而不至于直接中断事件循环。

通过上述实践,可以看出在asyncio框架下的并发编程中,合理运用try-except结构和理解任务取消及异常传递的机制,是确保异步应用在面对错误和异常时能够优雅处理的关键。

11、装饰器应用:异常装饰器的实现 🎨

装饰器是Python中一种强大的功能,用于修改或增强函数或类的行为。在异常处理场景中,装饰器可以用来统一处理函数抛出的异常,提升代码的整洁度和可复用性。

11.1 基础装饰器包裹异常

基础的异常处理装饰器可以捕获并处理被装饰函数可能抛出的异常 ,提供统一的错误处理逻辑。

def exception_handler(func):
    def wrapper(*args, **kwargs):
        try:
            return func(*args, **kwargs)
        except Exception as e:
            print(f"捕获到异常: {e}")
            # 这里可以加入更多处理逻辑,如记录日志、发送通知等
    return wrapper

@exception_handler
def divide(x, y):
    return x / y

print(divide(10, 2))  # 正常输出: 5.0
print(divide(10, 0))  # 输出: 捕获到异常: division by zero

在这个例子中,exception_handler装饰器捕获了divide函数因除零而引发的异常 ,并打印了异常信息 ,避免了程序直接崩溃。

11.2 参数化装饰器定制行为

为了增加装饰器的灵活性,可以使其接受参数,以便根据不同的参数值定制异常处理的行为。例如,下面的装饰器允许指定是否记录异常到日志文件。

import logging

def log_exceptions(log_to_file=False):
    def decorator(func):
        def wrapper(*args, **kwargs):
            try:
                return func(*args, **kwargs)
            except Exception as e:
                print(f"捕获到异常: {e}")
                if log_to_file:
                    logging.error(f"异常信息: {e}", exc_info=True)
        return wrapper
    return decorator

logging.basicConfig(filename='app.log', level=logging.ERROR)

@log_exceptions(log_to_file=True)
def divide_with_logging(x, y):
    return x / y

print(divide_with_logging(10, 0))  # 除了打印异常 ,还会记录到app.log文件中

通过向log_exceptions装饰器传递log_to_file=True参数,实现了在捕获异常时同时将错误信息记录到日志文件的功能 ,展示了装饰器参数化定制异常处理行为的能力。

通过上述示例,可以看出装饰器在异常处理方面的作用不仅限于简化代码结构 ,还能通过参数化设计提供更加灵活和定制化的异常管理策略,有效提升代码的健壮性和维护性。

12、性能考量:异常使用的性能影响 🚦

在Python应用中,合理使用异常处理机制对于提升程序的健壮性至关重要,但同时也需注意其对性能的影响。本章将探讨异常捕获的开销及避免将异常作为常规程序控制流手段的策略。

12.1 异常捕获的开销

异常处理在Python中相对昂贵,特别是在异常被频繁触发的场景下。每次异常抛出和捕获都会消耗额外的CPU周期,包括堆栈展开、异常对象的创建、以及异常处理逻辑的执行。因此,在性能敏感的代码段 ,减少不必要的异常使用是非常必要的。

import timeit

def with_exception_check(num):
    if num == 0:
        raise ValueError("Invalid value")
    return 10 / num

def without_exception(num):
    if num != 0:
        return 10 / num
    else:
        return None  # 或者其他处理方式

# 测试两种情况的性能差异
exception_time = timeit.timeit('with_exception_check(0)', globals=globals(), number=10000)
no_exception_time = timeit.timeit('without_exception(0)', globals=globals(), number=10000)

print(f"异常处理耗时: {exception_time}")
print(f"无异常处理耗时: {no_exception_time}")

通过比较带异常处理和不带异常处理的函数执行时间 ,可以直观感受到异常捕获的性能开销。

12.2 避免异常作为程序流程控制

尽管异常可以作为一种控制流的手段,比如用于替代条件判断 ,但这并不是其设计初衷。频繁使用异常来控制程序流程不仅会影响性能,还可能导致代码逻辑难以理解和维护。

例如 ,以下代码通过异常来判断文件是否存在,而不是预先检查:

def read_file_contents(filename):
    try:
        with open(filename, 'r') as file:
            return file.read()
    except FileNotFoundError:
        return "文件未找到"

# 更好的做法是预先检查文件存在
def read_file_contents_optimized(filename):
    import os
    if os.path.exists(filename):
        with open(filename, 'r') as file:
            return file.read()
    else:
        return "文件未找到"

read_file_contents_optimized中,通过先检查文件是否存在来避免异常 ,这种方式在性能敏感的应用中更为推荐 ,同时代码也更清晰易读。

总之,在设计程序时,应审慎考虑异常的使用 ,尽量减少异常的触发频率,避免将其作为日常逻辑控制手段 ,以确保程序既健壮又高效。

13、总结 🚀

探索Python异常处理的深度策略,从基础的try-except结构到自定义异常类的创建,再到利用上下文管理器和装饰器提升代码健壮性。深入理解异常传递机制 ,掌握日志记录与并发环境下异常处理的关键实践 ,强调了性能考量与避免异常作为控制流程的重要性。本系列概述了实现精准异常管理的全方位技巧 ,助力开发者构建稳定、高效的Python应用程序。

最后 如果你对Python感兴趣的话,可以试试我整理的这份Python全套学习资料,【点击这里】领取!

包括:Python激活码+安装包、Python web开发,Python爬虫,Python数据分析,人工智能、自动化办公等学习教程。带你从零基础系统性的学好Python!
Python所有方向的学习路线图,清楚各个方向要学什么东西
100多节Python课程视频,涵盖必备基础、爬虫和数据分析
100多个Python实战案例,学习不再是只会理论
华为出品独家Python漫画教程,手机也能学习
历年互联网企业Python面试真题,复习时非常方便******

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1984919.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

简单的docker学习 第3章 docker镜像

第3章 Docker 镜像 3.1镜像基础 3.1.1 镜像简介 ​ 镜像是一种轻量级、可执行的独立软件包&#xff0c;也可以说是一个精简的操作系统。镜像中包含应用软件及应用软件的运行环境。具体来说镜像包含运行某个软件所需的所有内容&#xff0c;包括代码、库、环境变量和配置文件等…

尚硅谷谷粒商城项目笔记——三、安装docker【电脑CPU:AMD】

三、安装docker 注意&#xff1a; 因为电脑是AMD芯片&#xff0c;自己知识储备不够&#xff0c;无法保证和课程中用到的环境一样&#xff0c;所以环境都是自己根据适应硬件软件环境重新配置的&#xff0c;这里的虚拟机使用的是VMware。 首先关闭防火墙和安全策略 systemctl…

nature子刊真实案例,录用仅需1个月!1区SCI,截稿在即!

关注GZH【欧亚科睿学术】&#xff0c;第一时间了解期刊最新动态&#xff01; &#x1f680; &#x1f680; &#x1f680; &#x1f680; 快到飞起&#xff01;这本毕业神刊竟1个月秒录&#xff01; SCI期刊信息简介 【期刊类型】工程综合类SCIE&#xff08;1个月17天…

mac chrome打开网页,莫名其妙的闪退

今天&#xff0c;突然有用户反馈更新到浏览器版本后&#xff0c;打开特定网页时&#xff0c;浏览器会出现闪退的情况。 经过对业务代码长时间的排查都没有发现具体的问题&#xff0c;于是想到使用“大数据排查”&#xff08;上网google下&#xff09;的方法&#xff0c;终于在茫…

【技巧】IDEA打断点增加条件控制

【技巧】IDEA打断点增加条件控制

03、DQL(数据查询语言)

目录 1、编写顺序 2、基本查询 3、条件查询 4、聚合函数 5、分组查询 6、排序查询 7、分页查询 8、执行顺序 1、编写顺序 SELECT 字段列表 FROM 表名列表 WHERE 条件列表 GROUP BY 分组字段列表 HAVING 分组后条件列表 ORDER BY 排序字段列表 LIMIT 分页参数2、基本查…

Visual C++ 下载、安装教程(微软常用运行库合集|dll报错必装)

前言 Microsoft Visual C Redistributable&#xff08;简称MSVC&#xff0c;VB/VC&#xff0c;系统运行库&#xff09;是Windows操作系统应用程序的基础类型库组件。此版Visual C运行库组件合集&#xff08;微软常用运行库合集&#xff09;由国内封装爱好者Dreamcast打包而成&…

C#学习笔记14:SYN6288语音模块_Winform上位机控制软件

今日尝试使用C# Winform写一个上位机软件控制 SYN6288语音模块 这里不讲什么基本原理(或者讲的比较略简)&#xff0c;直接讲实现了就...... 文章提供测试代码讲解、测试效果图、整体测试工程下载 目录 控件的摆放&#xff1a; SYN6288介绍: 代码编程&#xff1a; 对16进制发送…

计算机毕业设计选题推荐-出租车服务管理系统-Java/Python项目实战

✨作者主页&#xff1a;IT研究室✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Python…

ArrayList顺序表

目录 一、ArrayList变量的创建 二、ArrayList的三种构造方法 2.1 ArrayList() 2.2 ArrayList(int) 2.3 ArrayList(Collection) 三、ArrayList常用方法介绍 3.1 boolean add(E e) 3.2 E remove(int index) 和 boolean remove(Object o) 3.3 List subList(int fromInde…

hive udtf 函数:输入一个字符串,将这个字符串按照特殊的逻辑处理之后,输出4个字段

这里要继承GenericUDTF 这个抽象类,直接上代码: package com.xxx.hive.udf; import org.apache.commons.lang.StringUtils; import org.apache.hadoop.hive.ql.exec.Description; import org.apache.hadoop.hive.ql.exec.UDFArgumentException; import org.apache.hadoop.hi…

2024年最建议买哪几款蓝牙耳机?四大2024性价比王牌机型推荐

随着科技的飞速发展&#xff0c;蓝牙耳机已经从昔日的奢侈品转变为如今生活中的必需品。面对日益丰富的产品线和不断更新的技术特性&#xff0c;选择一款适合自己的蓝牙耳机变得越来越具有挑战性&#xff0c;那么在2024年最建议买哪几款蓝牙耳机&#xff1f;作为蓝牙耳机爱好者…

48天笔试训练错题——day42

目录 选择题 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 编程题 1. 走迷宫 选择题 1. 动态分配&#xff1a;使用 DHCP 协议动态分配 IP。 IP 地址不但有单播地址&#xff0c;多播地址&#xff0c;还有广播地址。 如果一个主机有块个网卡&#xff0c;那么每块网卡都可以拥…

人工智能时代,程序员如何保持核心竞争力,不会一觉醒来,被自己写的代码淘汰了 ≧ ﹏ ≦

随着AIGC&#xff08;人工智能生成内容&#xff09;技术的飞速发展&#xff0c;尤其是像ChatGPT、Midjourney、Claude等大语言模型的崛起&#xff0c;人工智能正以前所未有的速度渗透到编程领域&#xff0c;彻底改变了程序员的工作方式。这一变革既带来了挑战&#xff0c;也孕育…

2024/08 近期关于AI的阅读和理解[笔记]

#Cohere 就像商业能力很强的云数仓公司 Snowflake 一样&#xff0c;Cohere 也采用了按需付费模式而不是按月或按年付费&#xff0c;而且它的付费模式很精细。Cohere 按照模型的不同能力&#xff0c;包括文本生成&#xff0c;文本总结&#xff0c;重新排名&#xff0c;文本分类…

pikachu文件下载

一&#xff1a;简介 在许多 web 系统中都有文件下载功能&#xff0c;点击下载链接会向后台发送含文件名的下载请求&#xff0c;后台收到后执行下载代码将对应文件返回给浏览器完成下载。若后台收到文件名后直接拼进下载路径而不做安全判断&#xff0c;可能引发不安全的文件下载…

【楚怡杯】职业院校技能大赛 “Python程序开发”赛项样题四

一、竞赛任务概述 本赛项包括“网络爬虫”、“数据清洗”、“数据分析与可视化”、“机器学习”4个竞赛任务&#xff0c;各任务分值分别为15分、30分、35分、20分&#xff0c;本赛项满分为100分。 二、注意事项 1.请根据大赛所提供的竞赛环境&#xff0c;检查所列的硬件设备…

2024最新版Python基础入门学习路线

Python基础入门学习路线可以概括为以下几个阶段&#xff0c;每个阶段都包含了关键的学习内容和目标&#xff1a; 一、Python语言基础 1. 初识Python语言 Python语言概述&#xff1a;了解Python的起源、特点、应用领域以及发展趋势。环境安装&#xff1a;学习如何在不同的操作系…

Web API 渗透测试指南

概述 API&#xff08;Application Programming Interface&#xff0c;应用程序编程接口&#xff09;是一个允许不同软件应用程序之间进行通信和数据交换的接口。API定义了一组规则和协议&#xff0c;软件开发者可以使用这些规则和协议来访问操作系统、库、服务或其他应用程序的…

【HarmonyOS NEXT星河版开发学习】小型测试案例02-华为登录

个人主页→VON 收录专栏→鸿蒙开发小型案例总结​​​​​ 基础语法部分会发布于github 和 gitee上面&#xff08;还未发布&#xff09; 前言 通过此案例&#xff0c;不得不感叹鸿蒙的强大了&#xff0c;仅仅使用了26行代码就构建出来了这个界面&#xff0c;确实特别方便&#…