【Python零基础】类的概念

news2024/9/25 3:24:30

文章目录

  • 前言
  • 一、创建并使用类
  • 二、使用类和实例
  • 三、继承
  • 四、导入类
  • 五、Python标准库
  • 六、类的编码风格
  • 总结


前言

面向对象编程是现在使用最多的软件编写方法之一。面向对象中最核心的就是类(class),类用来描述现实世界的事物和情景,我们基于这些类来创建实例对象。类就是这些对象共有的属性和行为的抽象。举个例子——鸟类,鸟类共有的属性如一对翅膀,双爪。共有的行为如飞翔,进食。这样当我们创建一个鸟类的实例对象时,就自动拥有这些属性和行为。

在Python中,类是一种用户定义的数据类型,使用class关键字定义。类定义了一组相关的属性(数据成员)和方法(成员函数),用于描述一类对象的共同特征和行为。通过实例化类,可以创建具有相同特性和行为的具体对象。类支持封装、继承和多态等面向对象编程的核心概念,有助于提高代码的复用性和可维护性。

新手读者朋友暂且先不必关注什么是封装、继承、多态。后面慢慢的结合代码会理解。


一、创建并使用类

创建Student类

我们先来创建一个Student类,文件名为 student.py

class Student:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def student_info(self):
        return f"Student(name={self.name}, age={self.age})"

1.类的定义

class Student:

根据这个可以总结出类的定义模板为:

class ClassName

2.构造函数

   def __init__(self, name, age):
       self.name = name
       self.age = age
   

这个 init()方法是构造函数方法,是Python中类的最基本的默认方法,只能是这个名字,不能自行修改,前后有两个下划线是为了和普通方法做区分。我们自己定义的方法当然也可以使用下划线,但是实在是没有必要,还会引起混淆,分不清Python默认方法还是自定义方法。每个类在实列化时都会自动调用的方法,进行一些初始化的操作,如属性赋值等。构造函数中为当前的实例对象设置两个属性name和age

  • self是一个指向实例本身的引用,它是每个实例方法的第一个参数。在这个例子中,self代表创建的Student对象
  • name和age是传递给构造函数的参数,用于初始化Student对象的属性。
  • self.name = name 和 self.age = age 分别将传入的name和age值存储为对象的属性。

3.自定义方法

   def student_info(self):
       return f"Student(name={self.name}, age={self.age})"

这个是我们自定义的方法,返回学生信息,比较简单。

重点解释下这个 self 参数,每个方法默认第一个参数就是self,这个是必不可少的参数(除非你不想使用任何参数,那就不必传),并且必须位于其他形参的前面。Python调用_init_()方法时,会自动传入self参数。每个与实列对象相关联的方法,都会自动传递实参self,该实参是一个指向实例本身的引用,让实列能够访问实列中的属性和方法

这个self可以替换成其他的,比如this,但是我们写代码时不要去替换。使用self来表示当前实例的引用是默认的规则,更改反而不利于他人的阅读理解,属于画蛇添足

根据Student类创建一个实例

我们再创建一个test.py文件,在其中引入Student类

from student import Student

my_student = Student(name='John', age=30)

print(f"My name is {my_student.name}")

print(f"My age is {my_student.age}")

代码 **my_student = Student(‘John’, ‘Doe’)**就是Student类实例化的方式,我们传入了两个实参,分别对应方法 _init_(self, name, age)中的后两个参数,第一个self默认自动传入。 _init_()方法会自动返回一个实例,不需要显示的return

在这里插入图片描述

1.访问属性

如 my_student.name,my_student.age

实例名.属性名

2.调用方法

from student import Student

my_student = Student(name='John', age=30)

student_info = my_student.student_info()

print(student_info)

如 my_student.student_info(),调用了student_info()方法

实例名.方法名

3.创建多个实例

from student import Student

my_student1 = Student(name='John', age=30)

my_student2 = Student(name='Luke', age=25)

student_info1 = my_student1.student_info()

student_info2 = my_student2.student_info()

print(student_info1)

print(student_info2)

代码中创建了两个实例对象,分别调用了各自的实例方法 student_info

在这里插入图片描述


二、使用类和实例

创建Car类

class Car:
    """一次模拟汽车的简单尝试"""

    def __init__(self, make, model, year):
        """初始化描述汽车的属性"""
        self.make = make
        self.model = model
        self.year = year

    def get_descriptive_name(self):
        """返回整洁的描述性信息"""
        long_name = str(self.year) + ' ' + self.make + ' ' + self.model
        return long_name.title()


my_new_car = Car('audi', 'a4', 2016)

print(my_new_car.get_descriptive_name())

下面是对这段代码的详细解释

类定义

  • 类名:Car
  • 文档字符串:“一次模拟汽车的简单尝试”,用于描述类的功能。

初始化方法 init

  • 参数:
    • self:代表类的实例,是每个方法的第一个参数。
    • make:汽车制造商的名字。
    • model:汽车型号。
    • year:汽车生产年份。
  • 功能:
    • 初始化汽车的三个属性:制造商、型号和生产年份。
    • 这些属性通过 self.make、self.model 和 self.year 存储在实例中。

方法 get_descriptive_name

  • 功能:
    • 返回一个格式化的字符串,包含汽车的所有信息。
    • 字符串格式为:“YearMakeModel”,其中 Year 是四位数字的年份,Make 和 Model 分别是制造商和型号。
    • 使用 title() 方法将字符串中的单词首字母大写。

创建实例并调用方法

  • 实例化:
    • 创建了一个 Car 类的实例 my_new_car,传入了 “audi”、“a4” 和 2016 作为参数。
  • 调用方法:
    • 通过 my_new_car.get_descriptive_name() 调用了 get_descriptive_name 方法。
    • 输出结果:“2016AudiA4”,其中每个单词的首字母都被大写了。

在这里插入图片描述

给属性指定默认值

类中的每个属性都必须有初始值,哪怕这个值是0或空字符串。在有些情况下,如设置默认值时,在方法_init_()内指定这种初始值是可行的;如果你对某个属性这样做了,就无需包含为它提供初始值的形参。

class Car:
    def __init__(self, make, model, year):
        """初始化描述汽车的属性"""
        self.make = make
        self.model = model
        self.year = year
        # 设置初始值里程数 = 0
        self.odometer_reading = 0

    def get_descriptive_name(self):
        return str(self.year) + ' ' + self.make + ' ' + self.model
    def read_odometer(self):
        """打印一条指出汽车里程的消息"""
        print("This car has " + str(self.odometer_reading) + " miles on it.")


my_new_car = Car('audi', 'a4', 2016)
print(my_new_car.get_descriptive_name())
#读取里程数
my_new_car.read_odometer()

在这里插入图片描述
汽车里程odometer_reading的属性被我们指定成0

修改属性的值

可以以三种不同的方式修改属性的值:

  1. 直接通过实例进行修改
  2. 通过方法进行设置
  3. 通过方法进行递增(增加特定的值)​

1.直接通过实例进行修改

#设置里程数
my_new_car.odometer_reading = 30
#读取里程数
my_new_car.read_odometer()

调用读取里程数之前,先通过实例修改了属性值

在这里插入图片描述

2.通过方法修改属性的值

我们在car.py的Car类下面增加一个方法 update_odometer,用于修改里程值。
update_odometer()在修改属性前检查指定的读数是否合理。如果新指定的里程(mileage)大于或等于原来的里程(self.odometer_reading),就将里程表读数改为新指定的里程;否则就发出警告,指出不能将里程表往回拨。

    def update_odometer(self, mileage):
        """将里程表读数设置为指定的值"""
        if mileage >= self.odometer_reading:
            self.odometer_reading = mileage
        else:
            print("you can't roll back an odometer!")

接着调用方法,设置属性

#设置里程数
my_new_car.update_odometer(46)
#读取里程数
my_new_car.read_odometer()

控制台打印结果如下

This car has 46 miles on it.

3.通过方法让属性值递增
有时,我们需要对属性值进行递增操作,而不是完全替换,再提供一个递增方法

    def increment_odometer(self, miles):
        """将里程表读数增加指定的量"""
        self.odometer_reading += miles

递增调用的代码如下

#增加里程数
my_new_car.increment_odometer(10)
#读取里程数
my_new_car.read_odometer()

#增加里程数
my_new_car.increment_odometer(20)
#读取里程数
my_new_car.read_odometer()

打印结果如下

在这里插入图片描述
上述方法实际开发中,我们需要做好权限和风险控制,防止出现意外结果


三、继承

继承这个概念比较容易理解,并不是Python语言独有的,是面向对象编程思想的核心概念之一。从字面上来看,就是类属性和方法的复用,创建一个类继承另外一个类,那么这个类便拥有了继承那个类的属性和方法。创建的这个类叫子类,继承的类叫父类。子类继承了其父类的所有属性和方法,同时还可以定义自己的属性和方法。

子类中的__init__()方法

class Car:
    def __init__(self, make, model, year):
        """初始化描述汽车的属性"""
        self.make = make
        self.model = model
        self.year = year
        # 设置初始值里程数 = 0
        self.odometer_reading = 0

    def get_descriptive_name(self):
        return str(self.year) + ' ' + self.make + ' ' + self.model
    def read_odometer(self):
        """打印一条指出汽车里程的消息"""
        print("This car has " + str(self.odometer_reading) + " miles on it.")

    def update_odometer(self, mileage):
        """将里程表读数设置为指定的值"""
        if mileage >= self.odometer_reading:
            self.odometer_reading = mileage
        else:
            print("you can't roll back an odometer!")

    def increment_odometer(self, miles):
        """将里程表读数增加指定的量"""
        self.odometer_reading += miles


"""
继承
"""
class ElectricCar(Car):
    """电动汽车的独特之处"""
    def __init__(self, make, model, year):
        """初始化父类的属性"""
        super().__init__(make, model, year)


my_electric_car = ElectricCar('tesla', 'model s', 2016)
print(my_electric_car.get_descriptive_name())

class ElectricCar(Car)这种写法就是ElectricCar类继承自Car类,创建子类时,必须引入父类的代码。笔者这里是把父类和子类写在一个模块文件里了,如果父类是在一个单独的模块中,比如car.py,则需要引入,具体如下

在这里插入图片描述
子类继承父类的所有属性和方法,代码运行结果如下

在这里插入图片描述

重写父类中的方法

对于父类的方法,只要它不符合子类模拟的实物的行为,都可对其进行重写。为此,可在子类中定义一个这样的方法,即它与要重写的父类方法同名。这样,Python将不会考虑这个父类方法,而只关注你在子类中定义的相应方法。

父类代码如下

class Car:
    def __init__(self, make, model, year):
        """初始化描述汽车的属性"""
        self.make = make
        self.model = model
        self.year = year
        # 设置初始值里程数 = 0
        self.odometer_reading = 0

    def fill_gas_tank(self):
        return "跑的里程数为:"+str(self.odometer_reading)

在子类所在模块中定义一个同名的方法,要求参数个数、类型、顺序都要和父类保持一致。可选参数必须放在最后,子类可以省略可选参数。

把实例用作属性

在 Python 中,可以将一个类的实例作为另一个类的属性。这种做法允许你将不同类的对象组合在一起,形成更复杂的数据结构。

假设我们有两个类:Address 和 Person。我们将创建一个 Address 实例,并将其作为 Person 类的一个属性。

定义 Address 类

class Address:
    def __init__(self, street, city, state, zip_code):
        self.street = street
        self.city = city
        self.state = state
        self.zip_code = zip_code

    def display_address(self):
        return f"{self.street}, {self.city}, {self.state} {self.zip_code}"

定义 Person 类

class Person:
    def __init__(self, name, age, address):
        self.name = name
        self.age = age
        self.address = address  # 将 Address 类的实例作为属性

    def display_person_info(self):
        return f"Name: {self.name}, Age: {self.age}, Address: {self.address.display_address()}"

调用代码示例如下

# 创建 Address 实例
address = Address("123 Main St", "Anytown", "CA", "12345")

# 创建 Person 实例,并传入 Address 实例作为属性
person = Person("Alice", 30, address)

# 显示 Person 的信息
print(person.display_person_info())

以上示例中创建了一个Address类的实例,并作为属性传递给Person类

运行结果如下

在这里插入图片描述
笔者把这些代码都放在了一个模块中

在这里插入图片描述


四、导入类

实际开发场景是复杂的,我们不可能把所有逻辑都写在一个模块中,更不能写在一个类中。我们要考虑可维护性、可复用性。这就要求我们要合理的划分模块,建立类。不过这种只有经过大量的实战项目,代码练习才能具备相当的经验。目前我们只需要掌握以下内容即可。

导入单个类

首先新建一个address.py文件,其中代码如下

class Address:
    def __init__(self, street, city, state, zip_code):
        self.street = street
        self.city = city
        self.state = state
        self.zip_code = zip_code

    def display_address(self):
        return f"{self.street}, {self.city}, {self.state} {self.zip_code}"

再新建一个my_address.py文件,在这个文件中引入address.py中的Address类,实例化是一个对象my_address ,打印地址信息

from address import Address

my_address = Address("123 Main St", "Any town", "CA", "12345")

address_info = my_address.display_address()

print(address_info)

在一个模块中存储多个类

先建立一个player_characters.py文件,在其中新建几个不同游戏玩家角色的类Warrior、Mage、Archer

class Warrior:
    def __init__(self, name, strength=80, health=100):
        self.name = name
        self.strength = strength
        self.health = health

    def attack(self):
        return f"{self.name} attacks with a strength of {self.strength}!"

    def get_health(self):
        return f"{self.name}'s health is {self.health}."


class Mage:
    def __init__(self, name, intelligence=70, mana=120):
        self.name = name
        self.intelligence = intelligence
        self.mana = mana

    def cast_spell(self):
        return f"{self.name} casts a spell with an intelligence of {self.intelligence}!"

    def get_mana(self):
        return f"{self.name}'s mana is {self.mana}."


class Archer:
    def __init__(self, name, agility=90, arrows=50):
        self.name = name
        self.agility = agility
        self.arrows = arrows

    def shoot_arrow(self):
        if self.arrows > 0:
            self.arrows -= 1
            return f"{self.name} shoots an arrow! Arrows left: {self.arrows}"
        else:
            return f"{self.name} has no more arrows!"

    def get_arrows(self):
        return f"{self.name}'s arrows: {self.arrows}."

从一个模块中导入多个类

再新建一个game.py文件,导入上述player_characters.py文件中的三个类,分别实例化并调用其中的方法

from player_characters import Warrior, Mage, Archer

# 创建角色实例
warrior = Warrior("Thorin")

mage = Mage("Gandalf")

archer = Archer("Pergolas")

# 执行角色的动作
print(warrior.attack())
print(mage.cast_spell())
print(archer.shoot_arrow())
print(archer.shoot_arrow())

# 查看角色的状态
print(warrior.get_health())
print(mage.get_mana())
print(archer.get_arrows())

在这里插入图片描述

导入整个模块

笔者这里使用了别名module,不使用也可以,直接使用模块的名称player_characters调用其中的类进行实例化

import player_characters as module

# 创建角色实例
warrior = module.Warrior("Thorin")

mage = module.Mage("Gandalf")

archer = module.Archer("Pergolas")

# 执行角色的动作
print(warrior.attack())
print(mage.cast_spell())
print(archer.shoot_arrow())
print(archer.shoot_arrow())

# 查看角色的状态
print(warrior.get_health())
print(mage.get_mana())
print(archer.get_arrows())

**导入模块中的所有类 **

导入模块中的所有内容的语法如下,本质上没有区别

from player_characters import *

不推荐使用这种导入方式,原因有以下两点

  • 首先,如果只要看一下文件开头的import语句,就能清楚地知道程序使用了哪些类,将大有裨益;但这种导入方式没有明确地指出你使用了模块中的哪些类。这种导入方式还可能引发名称方面的困惑。如果你不小心导入了一个与程序文件中其他东西同名的类,将引发难以诊断的错误。这里之所以介绍这种导入方式,是因为虽然不推荐使用这种方式,但你可能会在别人编写的代码中见到它。
  • 需要从一个模块中导入很多类时,最好导入整个模块,并使用module_name.class_name语法来访问类。这样做时,虽然文件开头并没有列出用到的所有类,但你清楚地知道在程序的哪些地方使用了导入的模块;你还避免了导入模块中的每个类可能引发的名称冲突。

导入模块中少量类使用如下语法

from player_characters import Warrior, Mage, Archer

导入模块中大量类使用如下语法

import player_characters

五、Python标准库

Python标准库是一组模块,安装的Python都包含它。就是官方提供的工具类库,基础库,帮我们封装和实现好了许多复杂又常用的数据结构。

新建一个birthday_calculator.py的文件,这是一个提供计算距离下一个生日天数的工具类,其中使用了datetime、random两个标准库的函数

import datetime
import random


def days_until_birthday(birth_date):
    """
    计算距离下一个生日还有多少天。
    
    参数:
    birth_date (str): 生日日期,格式为 'YYYY-MM-DD'。
    
    返回:
    int: 距离下一个生日的天数。
    """
    today = datetime.date.today()
    next_birthday = datetime.datetime.strptime(birth_date, '%Y-%m-%d').date().replace(year=today.year)
    if next_birthday < today:
        next_birthday = next_birthday.replace(year=today.year + 1)
    return (next_birthday - today).days


def get_random_wish():
    """
    随机选择一条祝福语句。
    
    返回:
    str: 祝福语句。
    """
    wishes = [
        "祝你生日快乐,愿你拥有美好的一年!",
        "希望你的每一个愿望都能实现!",
        "愿你的每一天都充满阳光和笑容!",
        "愿你新的一岁更加精彩!",
        "生日快乐,愿你健康平安!"
    ]
    return random.choice(wishes)

再新建一个main.py文件,代码如下

from birthday_calculator import days_until_birthday, get_random_wish


def main():
    print("欢迎使用生日计算器!")
    birth_date = input("请输入你的生日(格式:YYYY-MM-DD): ")
    days_until = days_until_birthday(birth_date)
    print(f"距离你的下一个生日还有 {days_until} 天!")
    wish = get_random_wish()
    print(wish)


if __name__ == "__main__":
    main()

在这里插入图片描述


六、类的编码风格

在Python中,类的编码风格通常遵循PEP 8规范,这是Python官方推荐的编码风格指南。以下是关于类定义的一些关键编码风格要点:

1. 类名命名:

  • 类名应该使用CapWords(首字母大写)的命名方式,例如 MyClass。

2. 方法名命名:

  • 方法名应该使用小写字母加上下划线 _ 的方式,例如 my_method。

3. 空行:

  • 在类定义之间以及类的外部方法之间使用两个空行。
  • 在类的方法之间使用一个空行。

4. 文档字符串:

  • 类和方法都应该有文档字符串,用三引号括起来,放在类或方法的第一行。
  • 文档字符串应简洁地描述类或方法的目的和功能。

5. 私有成员:

  • 如果一个方法或属性不打算被外部使用,可以使用单下划线 _ 开头来标记为“私有”。
  • 如果是绝对不希望外部访问的,可以使用双下划线 __ 开头,但这不是强制性的。

6. 继承:

  • 继承时,在括号内指定父类名,例如 class Child(Parent):。

7. 初始化方法:

  • 类通常会有一个初始化方法 init,用于设置实例变量。

8. 方法参数:

  • 第一个参数通常是 self,代表实例本身。
  • 其他参数按照逻辑顺序排列。

9. 代码缩进:

  • 使用4个空格进行缩进,而不是制表符。

简单示例代码如下,我们实际开发中需要遵循这些规则,不要擅自自创规则,使得代码可读性很差。

class MyClass:
    """这是一个简单的类示例。"""

    def __init__(self, name):
        """初始化方法。

        参数:
            name (str): 实例的名字。
        """
        self.name = name

    def say_hello(self):
        """打印问候消息。"""
        print(f"Hello, {self.name}!")

总结

本文详细介绍了Python中有关类的创建和使用相关代码示例,介绍了标准库和代码风格的一些公共规则。通过练习,我们应该对类这个面向对象编程的核心概念有所领悟。

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

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

相关文章

信号的产生

文章目录 2 信号的产生2.1 键盘组合键2.2 命令和函数调用2.2.1 kill命令2.2.2 raise()函数2.2.3 abort()函数 2.3 硬件异常2.3.1 除0异常2.3.2 空指针异常2.3.3 OS如何感知这些异常--除0异常2.3.4 OS如何感知这些异常--空指针异常 2.4 软件条件2.4.1 13&#xff09;SIGPIPE信号…

yolov5关键点检测-实现溺水检测与警报提示(代码+原理)

基于YOLOv5的关键点检测应用于溺水检测与警报提示是一种结合深度学习与计算机视觉技术的安全监控解决方案。该项目通常会利用YOLOv5强大的实时目标检测能力&#xff0c;并通过扩展或修改网络结构以支持人体关键点检测&#xff0c;来识别游泳池或其他水域中人们的行为姿态。 项…

12-使用gateway作为微服务网关

本文介绍spring gateway的使用&#xff0c;包括配置文件和使用java代码配置&#xff0c;让大家了解spring gateway的用法。如果不了解什么是微服务网关&#xff0c;就先查查资料&#xff0c;网关相对来说是比较重要的微服务组件。 0、环境 springboot 2.4.2springcloud gatew…

游戏开发设计模式之装饰模式

目录 装饰模式在游戏开发中的具体应用案例是什么&#xff1f; 如何在Unity中实现装饰模式以动态扩展游戏对象的功能&#xff1f; 装饰模式与其他设计模式&#xff08;如适配器模式、代理模式&#xff09;相比&#xff0c;有哪些优势和劣势&#xff1f; 优势 劣势 与适配器…

唯众2024年高职人工智能实训室方案解读

随着人工智能&#xff08;AI&#xff09;技术在全球范围内的快速发展&#xff0c;越来越多的职业技术学院开始重视AI相关专业的建设和实训室的搭建。作为在人工智能教育领域有着丰富经验的企业&#xff0c;唯众针对2024年的市场需求&#xff0c;推出了一套全面的人工智能实训室…

软件设计师教程(第5版)第8章 算法设计与分析(更新中)

8.1 算法设计与分析的基本概念P416 8.1.1 算法P416 【算法】是对特定问题求解步骤的一种描述&#xff0c;它是指令的有限序列&#xff0c;其中每一条指令表示一个或多个操作。P416 一个算法还具有下列5个重要特性&#xff1a;【有穷】性、【确定】性、【可行】性、【输入】、…

Games101学习 - 线性代数综述

1. 叉积矩阵形式 叉乘矩阵形式通常在物理模拟中有运用&#xff0c;处理四元数旋转也类似这样的形式。 // 定义两个向量 A 和 B FVector A(1.0f, 2.0f, 3.0f); FVector B(4.0f, 5.0f, 6.0f);// 计算叉积 FVector CrossProduct FVector::CrossProduct(A, B);if (GEngine) {GEn…

CVPR2024满分论文:基于可变形三维高斯的高质量单目动态重建方法

一、摘要 隐式神经表征为动态场景的重建和渲染开辟了新的途径。然而&#xff0c;尖端的动态神经渲染方法严重依赖这些隐式表征&#xff0c;它们常常难以捕捉场景中物体的复杂细节。此外&#xff0c;隐式方法通常难以实现动态场景的实时渲染&#xff0c;限制了它们在多种任务中的…

Excel公式与图表自动化:在Python中操作Excel公式并自动化生成图表

目录 一、Python操作Excel公式 1.1 读取Excel文件 1.2 识别和处理公式 1.3 批量处理公式 二、自动化生成图表 2.1 使用pandas和matplotlib生成图表 2.2 使用xlwings在Excel中直接生成图表 2.3 自定义图表样式 2.4 自动化生成复杂图表 三、总结 在数据分析和自动化办公…

VMware Workstation Pro for Personal Use (For Windows) 17.0.0

VMware Workstation Pro for Personal Use (For Windows) 17.0.0 弄了半天终于找到下载地址了 现在VMware被博通&#xff08;broadcom&#xff09;收购且宣布了17.5版本的VMware Workstation Pro对个人用户免费许可使用。由于现在官网的下载方式有改变&#xff0c;故贴出来一…

【数学分析笔记】第2章第4节收敛准则(4)

2.数列极限 2.4 收敛准则 上节课举了一个例子 a N 1 1 2 p 1 3 p . . . 1 n p a_{N}1\frac{1}{2^{p}}\frac{1}{3^{p}}...\frac{1}{n^{p}} aN​12p1​3p1​...np1​ p > 1 p>1 p>1&#xff0c; { a n } \{a_{n}\} {an​}收敛 0 < p ≤ 1 0<p\le 1 0<p≤…

OpenStack——keystone认证服务

1、作用 认证授权 服务目录 2、组件 keystone-server keystone-DB 3、架构 ①组成 用户认证流程&#xff1a; 1.Horizon为用户提供界面; 2.用户输入用户名密码&#xff0c;有Horizon转发至Keystone做认证授权 ; 3.如果认证鉴权成功&#xff0c;会给用户发放一个临时的unscope…

AIGC:Flux.1 NF4 使用 diffusers 推理

背景介绍 Flux 参数量很大 (包括 ext encoder2, autoencoder, 以及 diffusion model) , 使用Diffusers推理,显存占用 30GB。 有大佬做了 NF4 版本,效果依旧能打。所以本文使用 diffusers 推理 NF4版本的 Flux.1 本文重点 1:flux.1-dev-nf4 国内镜像加速下载 2:依赖环境…

error: undefined reference to `__imp__ZN11QSerialPortC1EP7QObject‘

问题 在qt console程序里使用QSerialPot, 在.pro文件里添加了serialport&#xff0c;在main.cpp里也包含了QtSerialPort/QSerialPort&#xff0c;但是编译报错如下&#xff1a; 原因 serialport模块加错了位置&#xff0c;应该添加到QT后面&#xff0c;而实际添加到CONFIG后…

mybatis-plus中Swagger 模式和Kotlin 模式是什么?

在 MyBatis-Plus 中&#xff0c;Swagger 模式和 Kotlin 模式是为了支持特定技术栈和开发需求的两种配置选项。它们分别针对 API 文档生成和 Kotlin 语言提供了更好的支持和集成。 Swagger 模式 Swagger 模式主要用于生成 API 文档。在 MyBatis-Plus 中启用 Swagger 模式后&am…

视频合并怎么弄?高效方法立即学

记得那次家庭聚会&#xff0c;我翻看着那些珍贵的录像带&#xff0c;突然萌生了一个想法&#xff1a;要是能把这些零散的记忆片段合并成一部完整的影片&#xff0c;那该多好啊&#xff01; 于是我开始了视频合并剪辑的探索之旅。从一开始的手足无措&#xff0c;到逐渐熟悉每一…

linux,ubuntu,使用ollama本地部署大模型llama3,模型通用,简易快速安装

文章目录 前言安装ollama启动ollama运行llama3模型查看ollama列表删除模型通过代码进行调用REST API 前言 在拥有了一条4090显卡后&#xff0c;那冗余的性能让你不得不去想着办法整花活&#xff0c;于是就想着部署个llama3&#xff0c;于是发现了ollama这个新大陆&#xff0c;…

【硬件操作入门】2--GPIO与门电路、二极管三极管、LED电路与操作

【硬件操作入门】2–GPIO与门电路&#xff08;二极管&三极管&#xff09;、LED电路与操作 文章目录 【硬件操作入门】2--GPIO与门电路&#xff08;二极管&三极管&#xff09;、LED电路与操作一、GPIO与门电路1.1、GPIO的应用1.2、GPIO引脚操作1.2.1 设置引脚为GPIO功能…

今日算法:蓝桥杯基础题之“切面条”

你好同学&#xff0c;我是沐爸&#xff0c;欢迎点赞、收藏、评论和关注&#xff01;个人知乎 从今天开始&#xff0c;一起了解算法&#xff0c;每日一题&#xff0c;从 JavScript 的技术角度进行解答&#xff0c;如果你对算法也感兴趣&#xff0c;请多多关注哦。 问题描述 一…

网络维护~2003服务环境

一、2003服务环境 背景&#xff1a;学习测试需要在虚拟机进行实验&#xff0c;主机kali验证开源十大漏洞&#xff0c;部分需要2003服务环境。 博客声明:搭建网络是为了学习用途&#xff0c;请遵守《网络安全法》. 二、安装iis服务软件 &#xff08;一&#xff09;查看Internet…