精通 Python 装饰器:代码复用与功能增强技巧

news2024/10/5 16:32:14

精通 Python 装饰器:代码复用与功能增强技巧

    • 引言
    • 装饰器基础
      • 装饰器的定义
      • 基本装饰器的实现方法
      • 理解 `@` 符号的用法
      • 简单装饰器示例代码
    • 使用装饰器增强函数功能
      • 日志记录
      • 性能测试
      • 事务处理
      • 小结
    • 装饰器进阶应用
      • 管理用户认证
      • 缓存机制的实现
      • 参数化装饰器的创建和应用
      • 多个装饰器的堆叠使用
      • 小结
    • 类装饰器
      • 类装饰器与函数装饰器的比较
      • 使用类实现装饰器逻辑
      • 类装饰器的应用场景和示例
      • 小结
    • 装饰器的高级话题
      • 装饰器与闭包的关系
      • 使用装饰器改变函数签名
      • 解决装饰器堆叠时的参数问题
      • 动态决定是否应用装饰器
      • 小结
    • 实战案例:使用装饰器解决实际问题
      • 使用装饰器简化 Flask/Django 应用中的视图权限控制
      • 通过装饰器实现的插件注册机制
      • 动态修改类的属性和方法
      • 小结
    • 总结与展望
      • 装饰器的优点
      • 装饰器的局限性
      • 未来趋势
      • 结语

在这里插入图片描述

引言

在 Python 的世界里,装饰器是一种强大的编程工具,它允许程序员在不改变原有函数定义的前提下,增加额外的功能。装饰器通过一种简洁优雅的方式实现了代码的复用和功能的扩展,极大地提高了代码的可读性和可维护性。不论是在简单的日志记录,还是复杂的权限验证、缓存机制中,装饰器都扮演着不可或缺的角色。

随着 Python 在Web开发、数据分析、人工智能等领域的流行,掌握装饰器变得尤为重要。它不仅仅是一个提升代码质量的工具,更是一种让代码更加 Pythonic 的编程哲学。通过本文的学习,读者将能够深入理解装饰器的工作原理,掌握其使用方法,并能够在实际项目中灵活运用装饰器解决各种问题。

接下来,我们将从装饰器的基础概念开始,逐步深入到它的高级应用,通过丰富的示例代码展示装饰器的强大能力。无论您是中级还是高级开发者,都能在本文中找到对您有用的信息和灵感。让我们一起开始这段探索之旅吧。

装饰器基础

装饰器的定义

在 Python 中,装饰器本质上是一个函数,它可以让其他函数在不改变源代码的情况下增加额外的功能。装饰器接收一个函数作为参数,并返回一个新的函数,新函数通常会加上一些额外的操作,然后返回原函数或者是经过修改的函数。

基本装饰器的实现方法

实现一个最基本的装饰器涉及到定义一个接收函数为参数的函数。这个装饰器函数内部通常会定义另外一个函数,用来包裹原有函数的调用,从而在原有函数执行前后添加额外的逻辑。

def my_decorator(func):
    def wrapper():
        print("Something is happening before the function is called.")
        func()
        print("Something is happening after the function is called.")
    return wrapper

@my_decorator
def say_hello():
    print("Hello!")

say_hello()

在这个例子中,my_decorator 是一个装饰器,它内部定义了一个 wrapper 函数。当 say_hello 函数被调用时,实际上是在调用 wrapper 函数。因此,除了 say_hello 函数本身会打印 “Hello!”,wrapper 函数还会在调用前后打印额外的信息。

理解 @ 符号的用法

在 Python 中,@ 符号是用来应用装饰器的语法糖。如上例所示,@my_decorator 直接放在函数定义前面,这样就可以将 say_hello 函数传递给 my_decorator 装饰器。这种写法让装饰器的应用更加直观和方便。

简单装饰器示例代码

装饰器不仅限于无参数的函数,它们也可以装饰带有参数的函数。为了让装饰器更加通用,可以使用 *args**kwargs 来接受任意数量的参数。

def my_decorator(func):
    def wrapper(*args, **kwargs):
        print("Something is happening before the function is called.")
        result = func(*args, **kwargs)
        print("Something is happening after the function is called.")
        return result
    return wrapper

@my_decorator
def say_hello(name):
    print(f"Hello, {name}!")

say_hello("World")

通过使用 *args**kwargs,我们可以确保装饰器对于不同签名的函数同样适用,这样就大大增强了装饰器的灵活性和实用性。

接下来,我们将探索如何使用装饰器增强函数功能,包括但不限于日志记录、性能测试和事务处理等实际应用场景。

使用装饰器增强函数功能

装饰器的一个核心作用是增强函数的功能,在不修改原始代码的情况下给函数添加新的行为。这一节将通过几个常见的实际应用场景,展示如何使用装饰器来实现这些功能增强。

日志记录

在软件开发过程中,日志记录是一项基本而重要的任务。使用装饰器可以轻松地为任何函数添加日志功能,从而跟踪函数的调用情况。

import logging

def log_decorator(func):
    def wrapper(*args, **kwargs):
        logging.info(f"{func.__name__} was called")
        return func(*args, **kwargs)
    return wrapper

@log_decorator
def say_hello(name):
    print(f"Hello, {name}")

say_hello("Python")

这个例子中,log_decorator 装饰器在被装饰的函数执行前记录了一条日志,指明了哪个函数被调用了。这对于调试和监控应用程序的运行非常有帮助。

性能测试

另一个常见用途是测量函数的执行时间,这对于性能优化尤为重要。装饰器能够提供一个简单的方式来实现这一功能。

import time

def timing_decorator(func):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        print(f"{func.__name__} took {end_time-start_time:.4f} seconds to complete.")
        return result
    return wrapper

@timing_decorator
def slow_function():
    time.sleep(2)

slow_function()

这里的 timing_decorator 装饰器在函数执行前后分别记录时间,然后计算并打印出函数的执行时间。

事务处理

装饰器也经常用于管理数据库事务。这是通过在执行数据库操作的函数前后,添加事务开始和提交或回滚来实现的。

def transaction_decorator(func):
    def wrapper(*args, **kwargs):
        print("Starting a database transaction")
        result = func(*args, **kwargs)
        print("Committing the transaction")
        return result
    return wrapper

@transaction_decorator
def update_database():
    print("Updating database records")

update_database()

在这个简化的例子中,transaction_decorator 模拟了数据库事务的处理过程:在函数执行前后分别打印出了开始和提交事务的信息。在实际应用中,这里的打印语句可以替换为真正的数据库事务控制命令。

小结

通过这些例子,我们可以看到装饰器如何通过一种非侵入式的方式来增强函数的功能。装饰器的这种灵活性使得它成为 Python 编程中不可或缺的工具之一。接下来,我们将探讨装饰器的进阶应用,包括参数化装饰器的创建和使用、以及多个装饰器的堆叠使用等高级话题。

装饰器进阶应用

装饰器的应用不仅限于函数功能的简单增强。通过更高级的使用方式,装饰器可以在更复杂的场景下发挥重要作用,如管理用户认证、实现缓存机制、参数化装饰器的创建和应用,以及多个装饰器的堆叠使用。

管理用户认证

在Web应用中,装饰器经常用于处理用户认证。通过在路由处理函数之前进行用户认证检查,可以确保只有授权的用户才能访问特定的资源。

def auth_decorator(func):
    def wrapper(*args, **kwargs):
        user_authenticated = check_user_authentication() # 假设这是一个检查用户是否认证的函数
        if not user_authenticated:
            raise Exception("用户未认证,无法访问")
        return func(*args, **kwargs)
    return wrapper

@auth_decorator
def sensitive_function():
    print("访问了敏感资源")

# sensitive_function() 在这里会进行用户认证检查

缓存机制的实现

装饰器也常用于实现缓存机制,通过存储函数的返回结果来避免重复执行计算密集型或耗时的操作。

from functools import lru_cache

@lru_cache(maxsize=100) # Python标准库提供的缓存装饰器
def expensive_function(param):
    # 这里是一些计算密集型或耗时的操作
    return result

# 对于相同的参数值,expensive_function 只会执行一次,后续调用会直接返回缓存的结果

参数化装饰器的创建和应用

装饰器可以设计为接受参数,这样就可以在应用装饰器时提供更多的灵活性。参数化装饰器通常需要使用一个外层函数来接收装饰器参数,然后返回一个实际的装饰器。

def repeat(times):
    def decorator_repeat(func):
        def wrapper(*args, **kwargs):
            for _ in range(times):
                result = func(*args, **kwargs)
            return result
        return wrapper
    return decorator_repeat

@repeat(times=3)
def print_message(message):
    print(message)

print_message("Hello, World!")

多个装饰器的堆叠使用

Python 允许在一个函数上堆叠多个装饰器,这些装饰器会按照从内到外的顺序执行。

@decorator_one
@decorator_two
def my_function():
    pass

# 等价于
# my_function = decorator_one(decorator_two(my_function))

通过这种方式,可以组合多个装饰器,为函数提供复合的功能增强。

小结

随着对装饰器深入的理解和应用,开发者可以在保持代码清晰和简洁的同时,实现复杂的功能需求。装饰器的这些进阶应用展示了其在实际开发中的强大能力和灵活性。接下来,我们将探讨类装饰器,这是另一种强大的工具,用于在类定义层面上应用装饰器的概念。

类装饰器

类装饰器是一种使用类实现的装饰器,它提供了一种在类定义层面上修改或增强类的功能的方式。与函数装饰器类似,类装饰器也是接收一个类作为参数,并返回一个新的类或者对原有类进行修改后的结果。

类装饰器与函数装饰器的比较

类装饰器和函数装饰器在概念上是相似的,都是为了增强某个对象(函数或类)的功能而存在。不同之处在于,类装饰器主要用于操作类 —— 比如添加、修改类的属性和方法,或者对类的实例化过程进行控制。

使用类实现装饰器逻辑

类装饰器通常通过定义一个实现了 __call__ 方法的类来实现。这个方法让一个类的实例可以像函数一样被调用,这正是类装饰器工作的基础。

class MyDecorator:
    def __init__(self, func):
        self.func = func

    def __call__(self, *args, **kwargs):
        # 在被装饰的函数执行前可以添加一些逻辑
        print("装饰器逻辑执行前")
        result = self.func(*args, **kwargs)
        # 在被装饰的函数执行后可以添加一些逻辑
        print("装饰器逻辑执行后")
        return result

@MyDecorator
def say_hello():
    print("Hello!")

say_hello()

类装饰器的应用场景和示例

类装饰器的一个常见应用场景是资源管理和控制,例如管理数据库连接的打开和关闭,或者自动化测试中的设置和清理工作。

class ResourceDecorator:
    def __init__(self, cls):
        self.cls = cls

    def __call__(self, *args, **kwargs):
        print("资源准备工作")
        instance = self.cls(*args, **kwargs)
        print("资源清理工作")
        return instance

@ResourceDecorator
class MyClass:
    def __init__(self):
        print("MyClass 的实例化")

my_instance = MyClass()

在这个例子中,ResourceDecorator 类装饰器在类 MyClass 的实例化前后添加了资源准备和清理的逻辑。

小结

类装饰器为Python提供了一种强大的机制,用于在不修改类定义的情况下增强和修改类的行为。通过使用类装饰器,开发者可以在更高的抽象层面上控制和管理类的行为,这在许多高级编程场景中非常有用。

接下来,我们将探讨装饰器的一些高级话题,包括装饰器与闭包的关系,使用装饰器改变函数签名,以及动态决定是否应用装饰器等内容。这些话题将帮助开发者更深入地理解装饰器的工作原理和应用范围。

装饰器的高级话题

装饰器是 Python 中一个强大的功能,不仅仅局限于简单地增加函数执行前后的操作。它们可以用于更复杂的编程模式,如动态修改函数行为、基于条件的装饰器应用、以及与闭包的深入结合等。这一节我们将探讨一些装饰器的高级话题。

装饰器与闭包的关系

装饰器和闭包密切相关。事实上,装饰器本身就是利用闭包的概念来实现的。闭包指的是一个函数记住了其外部作用域的变量,即使外部作用域的执行已经结束。装饰器利用闭包来记住原始函数,以及可能的装饰器参数,从而在调用时可以执行额外的逻辑。

使用装饰器改变函数签名

装饰器可以修改或包装原始函数的行为,这包括改变函数的签名。通过在装饰器内部定义包装函数时使用 *args**kwargs,可以确保装饰器对各种签名的函数都是适用的。但是,如果需要修改函数签名,例如添加、删除或更改参数,就需要更细致地操作这些参数。

解决装饰器堆叠时的参数问题

当多个装饰器被应用到同一个函数时,可能会遇到参数不匹配的问题。这是因为每个装饰器都可能会改变函数的签名。解决这个问题的一种方法是使用 functools.wraps 装饰器,它可以帮助保持原始函数的名称、文档字符串、注解和模块信息。

from functools import wraps

def my_decorator(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        # 执行一些操作
        return func(*args, **kwargs)
    return wrapper

动态决定是否应用装饰器

有时候,我们可能需要基于某些条件动态地决定是否应用装饰器。这可以通过在装饰器内部检查这些条件,并相应地调整装饰器的行为来实现。

def conditional_decorator(condition):
    def actual_decorator(func):
        if condition:
            @wraps(func)
            def wrapper(*args, **kwargs):
                # 执行装饰器增加的功能
                return func(*args, **kwargs)
            return wrapper
        else:
            # 如果不满足条件,返回原始函数
            return func
    return actual_decorator

这个示例展示了如何根据传递给 conditional_decorator 的条件来决定是否对函数应用装饰器。

小结

装饰器是 Python 编程中一个非常强大和灵活的特性,通过掌握其高级应用,开发者可以在不改变原始代码的情况下,灵活地增加或修改程序的功能。这些高级话题的探讨为我们提供了对装饰器更深层次的理解,展示了它们在复杂编程问题中的应用潜力。

接下来,我们将通过一些实战案例,看看如何将装饰器应用到解决实际问题中,如在 Flask 或 Django 应用中进行视图权限控制,实现插件注册机制,以及动态修改类的属性和方法等。

实战案例:使用装饰器解决实际问题

装饰器在实际编程中的应用范围极广,可以解决诸多编程问题,提高代码的可维护性和可读性。本节将通过几个实战案例来展示如何在具体场景中应用装饰器。

使用装饰器简化 Flask/Django 应用中的视图权限控制

在Web开发中,控制用户对不同视图的访问权限是一个常见需求。装饰器可以用来简化这一过程,使得权限控制更加直观和容易管理。

from functools import wraps
from flask import session, redirect

def login_required(func):
    @wraps(func)
    def decorated_function(*args, **kwargs):
        if 'user_id' not in session:
            # 如果用户未登录,则重定向到登录页面
            return redirect('/login')
        return func(*args, **kwargs)
    return decorated_function

# 在Flask视图函数中使用
@app.route('/secret-page')
@login_required
def secret_page():
    return 'This is a secret page'

在这个例子中,login_required 装饰器检查用户是否已经登录(即 session 中是否存在 user_id)。如果用户未登录,请求将被重定向到登录页面。

通过装饰器实现的插件注册机制

装饰器可以用来实现插件的自动注册机制,使得插件的发现和加载变得更加简单。

# 插件注册装饰器和插件存储容器
plugins = {}

def register_plugin(func):
    plugins[func.__name__] = func
    return func

@register_plugin
def my_plugin():
    print("This is my plugin")

# 使用插件
for plugin_name, plugin_func in plugins.items():
    print(f"Executing plugin {plugin_name}")
    plugin_func()

这个例子中,register_plugin 装饰器将函数自动注册为插件,存储在 plugins 字典中。这种机制可以用于开发可扩展的应用程序,其中插件可以在不修改主应用代码的情况下添加新的功能。

动态修改类的属性和方法

类装饰器不仅可以用于实例化前后的资源管理,还可以用来动态地修改类的属性和方法。

def add_class_methods(cls):
    cls.new_method = lambda self: "This is a new method"
    return cls

@add_class_methods
class MyCustomClass:
    pass

instance = MyCustomClass()
print(instance.new_method())  # 输出: This is a new method

在这个例子中,add_class_methods 类装饰器为 MyCustomClass 动态添加了一个新的方法。这展示了装饰器在动态编程中的应用,允许开发者在运行时修改类的行为。

小结

通过这些实战案例,我们看到了装饰器在实际开发中的强大应用,从Web应用的权限控制、插件机制的实现,到动态编程的应用,装饰器都能提供优雅且强大的解决方案。掌握装饰器的使用,可以让开发者在保持代码整洁的同时,实现复杂的编程任务。

接下来,我们将总结本文的内容,并对装饰器的未来应用趋势进行展望。

总结与展望

本文深入探讨了 Python 中装饰器的概念、基础应用、进阶技巧以及实战案例,展示了装饰器如何成为提高代码复用性、增强函数功能、以及优化应用架构的强大工具。从简单的日志记录和性能测试到复杂的权限控制和动态编程,装饰器都展现出了其灵活和强大的能力。

装饰器的优点

  • 代码复用:通过装饰器,可以轻松实现横切关注点(如日志、权限校验等)的复用,减少代码重复。
  • 代码组织:装饰器提供了一种清晰的方式来增强函数功能,有助于维护代码的组织性和可读性。
  • 灵活性:装饰器的设计让它在不修改原有函数定义的情况下增加额外功能,提供了极大的灵活性。

装饰器的局限性

尽管装饰器非常强大,但在使用时也需要注意其局限性:

  • 可读性问题:过度使用或不当使用装饰器可能会使代码难以理解,特别是对于初学者。
  • 性能考虑:装饰器会略微增加函数调用的开销,虽然通常不显著,但在性能敏感的应用中需要注意。

未来趋势

随着编程范式的发展,装饰器在 Python 中的应用将会越来越广泛。特别是在异步编程、Web框架开发、以及云原生应用中,装饰器都将扮演着重要的角色。此外,随着类型提示和静态分析工具的普及,我们可能会看到类型安全的装饰器使用模式,进一步增强装饰器的实用性和安全性。

结语

装饰器是 Python 语言中一个非常强大和灵活的特性,合理使用装饰器可以大大提高代码的质量和开发效率。希望通过本文的学习,读者能够深入理解装饰器的工作原理和应用方法,将其应用到实际开发工作中,解决实际问题。

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

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

相关文章

unity

Unity官方下载_Unity最新版_从Unity Hub下载安装 | Unity中国官网 Unity Remote - Unity 手册 登陆账号,找到一个3d 免费资源 3D Animations & Models | Unity Asset Store unity 里面window->package Manager 里面可以看到自己的asset ,下载后…

xlsx.js读取本地文件,按行转成数组数据

1.下包 //1. npm install xlsx //2. yarn add xlsx2.结构 <template><input type"file" change"onFileChange" /> </template>3.代码 <script> import * as XLSX from xlsxexport default {methods: {onFileChange (event) {/…

基于SpringBoot的“学生成绩管理系统”的设计与实现(源码+数据库+文档+PPT)

基于SpringBoot的“学生成绩管理系统”的设计与实现&#xff08;源码数据库文档PPT) 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringBoot 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 登录界面图 管理员功能界面图 学生管理界面图…

解决方案∣解密新能源产业的供应链革新之路,助力行业驶入数字化转型“快车道”

近期&#xff0c;备受关注的2024年全国两会如期举行&#xff0c;国务院总理李强作政府工作报告中多次提到锂电产业链上下游。 政府工作报告指出&#xff0c;2023年&#xff0c;国内新能源汽车产销量分别达到958.7万辆和949.5万辆&#xff0c;占全球比重超60%&#xff0c;产销连…

OpenSearch 与 Elasticsearch:哪个开源搜索引擎适合您?

当谈论到搜索引擎产品时&#xff0c;Elasticsearch 和 OpenSearch 是两个备受关注的选择。它们都以其出色的功能和灵活性而闻名&#xff0c;但在一些方面存在一些差异。在本文中&#xff0c;我们将从功能和延展性、工具与资源、价格和许可这三个角度对这两个产品进行论述。通过…

柚见第十一期(前端页面开发)

创建队伍 便于控制样式,在外面套一层div 创建假数据模拟后端传来数据 //假数据模拟 const initFormData { "name": "", "description": "", "expireTime": "", "maxNum": 0, "passwor…

jvisualvm保姆级教程

这里写目录标题 背景步骤VisualVM是什么官网下载安装gc插件监控本地java项目我们看看有哪些监控指标 远程java应用监控JMXjstatd 总结 背景 在有时候我们需要分析java应用的一些内存、gc等情况进行性能分析。我们往往需要一些性能分析利器&#xff0c;而VisualVM算是其中一个&…

C# 用Trace.WriteLine输出调试信息无法查看

写程序就会遇见BUG&#xff0c;这时候在代码不同部位输出一些标记的信息对查找错误非常有必要&#xff0c;一般情况下我们都是使用Console.WriteLine()方法来打印信息到控制台窗口&#xff0c;但有时候使用Console.WriteLine()方法会存在不方便的情况&#xff0c;比如鄙人遇到的…

javaEE8(数据库编程课后习题1,2)

一&#xff1a; 二&#xff1a; 数据库内信息&#xff1a; 登录&#xff1a; 注册&#xff1a; Register.jsp <% page pageEncoding"UTF-8" import"java.sql.*"%> <!DOCTYPE html> <html lang"en"> <head> <…

微信支付商户号如何开通 0.2% 提现费率?

微信支付商户号如何开通 0.2% 提现费率&#xff1f; 先说结论&#xff1a;本地面对面收款0.2%有可能&#xff0c;但线上不可能0.2%&#xff01;因为没利润&#xff01; 天下没有免费的午餐&#xff0c;所以不要被骗了。 支付宝和微信商户的费率除了少数公共事业&#xff08;…

php集成修改数据库的字段

1.界面效果 2.代码 <?phpecho <form action"" method"post"><label for"table">表名:</label><input type"text" id"table" name"table"><br><div id"fieldsContaine…

算法——哈希王

242.有效的字母异位词 力扣题目链接(opens new window) 给定两个字符串 s 和 t &#xff0c;编写一个函数来判断 t 是否是 s 的字母异位词。 示例 1: 输入: s "anagram", t "nagaram" 输出: true 示例 2: 输入: s "rat", t "car&qu…

基于若依的ruoyi-nbcio流程管理系统自定义业务流程出现多个时相应的流程选择问题(一)

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码&#xff1a; https://gitee.com/nbacheng/ruoyi-nbcio 演示地址&#xff1a;RuoYi-Nbcio后台管理系统 更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码&#xff1a; https://gitee.com/nbacheng/n…

基于PLC全自动药品包装机系统的设计5.26

摘 要 在科技迅猛发展的今天&#xff0c;人民生活水平也在逐步上升的同时&#xff0c;我们国家的医药包装行业却停滞不前&#xff0c;仍停留在使用继电器控制系统生产产品&#xff0c;然而这种控制系统却有着不可靠&#xff0c;线路极其复杂&#xff0c;出现故障问题难以解决的…

接口日志:储存到MySQL数据库

1、定义一个日志注解&#xff0c;把模块的接口调用日志储存到数据库中。 2、后续可能会产生性能问题&#xff0c;但对于当前快速扩张的业务而言&#xff0c;这种过渡性的功能&#xff0c;还是可以接受的。 用法&#xff1a; 一、自定义注解对象 package com.pkg.modelname.ann…

罐头鱼AI短视频矩阵营销|视频批量剪辑|矩阵系统

AI批量视频剪辑系统是一款功能丰富的视频编辑软件&#xff0c;提供了以下主要功能&#xff1a; 首页显示&#xff1a;在首页上显示用户的登录状态、已绑定的账号数量以及最近上传的视频素材和新上传素材列表。 抖音账号绑定功能&#xff1a;用户可以绑定抖音账号&#xff0c;Q…

【Python】新手入门学习:什么是硬编码?如何避免硬编码?

【Python】新手入门学习&#xff1a;什么是硬编码&#xff1f;如何避免硬编码&#xff1f; &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教…

在ubuntu上安装FastSufer【本机安装】

亲测:FastSurfer分割并重建一个大脑需要1个小时,而freeSurfer需要8个小时。确实很快! 这里我在网页端搭建了一个小的工具包,里面集成了经典的freeSurfer和较快的FastSurfer。如果你不想安装或者手头没有linux设备,您也可以直接从以下网址直接使用,跳过繁琐的安装步骤!!…

基于PLC的智能楼宇控制系统设计

目录 摘要 2 第一章 绪论 5 1.1 引言 5 1.2 智能楼宇的课题背景 5 1.3 智能楼宇的功能和优势 6 第二章 智能楼宇系统总体方案确定 7 2.1 智能楼宇系统总体方案的设计 7 2.1.1 智能楼宇概述 7 2.1.2 智能楼宇的分类 7 1、建筑设备自动化系统(BA) 7 2、通讯自动化系统&#xff0…