Python Learn day05

九术AI

Python Learn day05

本文主要讲解 继承多态定制类

继承和多态

什么是继承

当新类想要拥有现有类的功能结构,可以使用继承。继承的前提是新类 is a 现有类,即: 子类 is 父类

总是从某个类继承:

class Myclass(object):pass

一定不要忘记调用super()._init_

def __init__(self,args):super(SubClass,self).__init__(args)pass

has 关系用组合而不是继承

继承一个类

如果已经定义了Person类,需要定义新的Student和Teacher类时,可以直接从Person类继承:

class Person(object):def __init__(self, name, gender):self.name = nameself.gender = gender

定义Student类时,只需要把额外的属性加上,例如score:

class Student(Person):def __init__(self, name, gender, score):super(Student, self).__init__(name, gender)self.score = score

一定要用 super(Student, self)._init_(name, gender) 去初始化父类,否则,继承自 Person 的 Student 将没有 name 和 gender。

函数super(Student, self)将返回当前类继承的父类,即 Person ,然后调用_init_()方法,注意self参数已在super()中传入,在_init_()中将隐式传递,不需要写出(也不能写)

判断类型

函数isinstance()可以判断一个变量的类型,既可以用在Python内置的数据类型如str、list、dict,也可以用在我们自定义的类,它们本质上都是数据类型。

假设有如下的 Person、Student 和 Teacher 的定义及继承关系如下:

class Person(object):def __init__(self, name, gender):self.name = nameself.gender = genderclass Student(Person):def __init__(self, name, gender, score):super(Student, self).__init__(name, gender)self.score = scoreclass Teacher(Person):def __init__(self, name, gender, course):super(Teacher, self).__init__(name, gender)self.course = coursep = Person('Tim', 'Male')
s = Student('Bob', 'Male', 88)
t = Teacher('Alice', 'Female', 'English')

当我们拿到变量 p、s、t 时,可以使用 isinstance 判断类型:

>>> isinstance(p, Person)
True    # p是Person类型
>>> isinstance(p, Student)
False   # p不是Student类型
>>> isinstance(p, Teacher)
False   # p不是Teacher类型

这说明在继承链上,一个父类的实例不能是子类类型,因为子类比父类多了一些属性和方法。

我们再考察 s :

>>> isinstance(s, Person)
True    # s是Person类型
>>> isinstance(s, Student)
True    # s是Student类型
>>> isinstance(s, Teacher)
False   # s不是Teacher类型

s 是Student类型,不是Teacher类型,这很容易理解。但是,s 也是Person类型,因为Student继承自Person,虽然它比Person多了一些属性和方法,但是,把 s 看成Person的实例也是可以的。

这说明在一条继承链上,一个实例可以看成它本身的类型,也可以看成它父类的类型。

多态

类具有继承关系,并且子类类型可以向上转型看做父类类型,如果我们从 Person 派生出 Student和Teacher ,并都写了一个 whoAmI() 方法:

class Person(object):def __init__(self, name, gender):self.name = nameself.gender = genderdef whoAmI(self):return 'I am a Person, my name is %s' % self.nameclass Student(Person):def __init__(self, name, gender, score):super(Student, self).__init__(name, gender)self.score = scoredef whoAmI(self):return 'I am a Student, my name is %s' % self.nameclass Teacher(Person):def __init__(self, name, gender, course):super(Teacher, self).__init__(name, gender)self.course = coursedef whoAmI(self):return 'I am a Teacher, my name is %s' % self.name

在一个函数中,如果我们接收一个变量 x,则无论该 x 是 Person、Student还是 Teacher,都可以正确打印出结果:

def who_am_i(x):print x.whoAmI()p = Person('Tim', 'Male')
s = Student('Bob', 'Male', 88)
t = Teacher('Alice', 'Female', 'English')who_am_i(p)
who_am_i(s)
who_am_i(t)

运行结果:

I am a Person, my name is Tim
I am a Student, my name is Bob
I am a Teacher, my name is Alice

这种行为称为多态。也就是说,方法调用将作用在 x 的实际类型上。s 是Student类型,它实际上拥有自己的 whoAmI()方法以及从 Person继承的 whoAmI方法,但调用 s.whoAmI()总是先查找它自身的定义,如果没有定义,则顺着继承链向上查找,直到在某个父类中找到为止。

由于Python是动态语言,所以,传递给函数 who_am_i(x)的参数 x 不一定是 Person 或 Person 的子类型。任何数据类型的实例都可以,只要它有一个whoAmI()的方法即可:

class Book(object):def whoAmI(self):return 'I am a book'

这是动态语言和静态语言(例如Java)最大的差别之一。动态语言调用实例方法,不检查类型,只要方法存在,参数正确,就可以调用。

多重继承

除了从一个父类继承外,Python允许从多个父类继承,称为多重继承。

多重继承的继承链就不是一棵树了,它像这样:

class A(object):def __init__(self, a):print 'init A...'self.a = aclass B(A):def __init__(self, a):super(B, self).__init__(a)print 'init B...'class C(A):def __init__(self, a):super(C, self).__init__(a)print 'init C...'class D(B, C):def __init__(self, a):super(D, self).__init__(a)print 'init D...'

D 同时继承自 B 和 C,也就是 D 拥有了 A、B、C 的全部功能。多重继承通过 super()调用_init_()方法时,A 虽然被继承了两次,但_init_()只调用一次:

>>> d = D('d')
init A...
init C...
init B...
init D...

多重继承的目的是从两种继承树中分别选择并继承出子类,以便组合功能使用。

举个例子,Python的网络服务器有TCPServer、UDPServer、UnixStreamServer、UnixDatagramServer,而服务器运行模式有 多进程ForkingMixin 和 多线程ThreadingMixin两种。

要创建多进程模式的 TCPServer:

class MyTCPServer(TCPServer, ForkingMixin)pass

要创建多线程模式的 UDPServer:

class MyUDPServer(UDPServer, ThreadingMixin):pass

如果没有多重继承,要实现上述所有可能的组合需要 4x2=8 个子类。

获取对象信息

拿到一个变量,除了用 isinstance() 判断它是否是某种类型的实例外,还有没有别的方法获取到更多的信息呢?

例如,已有定义:

class Person(object):def __init__(self, name, gender):self.name = nameself.gender = genderclass Student(Person):def __init__(self, name, gender, score):super(Student, self).__init__(name, gender)self.score = scoredef whoAmI(self):return 'I am a Student, my name is %s' % self.name

首先可以用 type() 函数获取变量的类型,它返回一个 Type 对象:

>>> type(123)<type 'int'>>>> s = Student('Bob', 'Male', 88)>>> type(s)<class '__main__.Student'>

其次,可以用 dir() 函数获取变量的所有属性:

>>> dir(123)   # 整数也有很多属性...['__abs__', '__add__', '__and__', '__class__', '__cmp__', ...]>>> dir(s)['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'gender', 'name', 'score', 'whoAmI']

对于实例变量,dir()返回所有实例属性,包括__class__这类有特殊意义的属性。注意到方法whoAmI也是 s 的一个属性。

如何去掉__xxx__这类的特殊属性,只保留我们自己定义的属性?回顾一下filter()函数的用法。

dir()返回的属性是字符串列表,如果已知一个属性名称,要获取或者设置对象的属性,就需要用 getattr() 和 setattr( )函数了:

>>> getattr(s, 'name')  # 获取name属性'Bob'>>> setattr(s, 'name', 'Adam')  # 设置新的name属性>>> s.name'Adam'>>> getattr(s, 'age')  # 获取age属性,但是属性不存在,报错:Traceback (most recent call last):File "<stdin>", line 1, in <module>AttributeError: 'Student' object has no attribute 'age'>>> getattr(s, 'age', 20)  # 获取age属性,如果属性不存在,就返回默认值20:20

定制类

什么是特殊方法

用于 print 的_str_

用于 len 的_len_

用于 cmp 的_cmp_

特点:

1.特殊方法定义在 class 中

2.不需要直接调用

3.Python 的某些函数或操作符会调用对应的特殊方法

正确实现特殊方法:

1.只需要编写需要的特殊方法

2.有关联性的特殊方法都必须实现

例如当我们实现_getattr_函数的时候就必须同时实现_setattr__delattr_

str__和__repr

如果要把一个类的实例变成 str,就需要实现特殊方法_str_()

class Person(object):def __init__(self, name, gender):self.name = nameself.gender = genderdef __str__(self):return '(Person: %s, %s)' % (self.name, self.gender)

现在,在交互式命令行下用 print 试试:

>>> p = Person('Bob', 'male')>>> print p(Person: Bob, male)

但是,如果直接敲变量 p:

>>> p<main.Person object at 0x10c941890>

似乎_str_() 不会被调用。

因为 Python 定义了_str_()_repr_()两种方法,_str_()用于显示给用户,而_repr_()用于显示给开发人员。

有一个偷懒的定义_repr_的方法:

class Person(object):def __init__(self, name, gender):self.name = nameself.gender = genderdef __str__(self):return '(Person: %s, %s)' % (self.name, self.gender)__repr__ = __str__

python中 _cmp_

对 int、str 等内置数据类型排序时,Python的 sorted() 按照默认的比较函数 cmp 排序,但是,如果对一组 Student 类的实例排序时,就必须提供我们自己的特殊方法 _cmp_()

class Student(object):def __init__(self, name, score):self.name = nameself.score = scoredef __str__(self):return '(%s: %s)' % (self.name, self.score)__repr__ = __str__def __cmp__(self, s):if self.name < s.name:return -1elif self.name > s.name:return 1else:return 0

上述 Student 类实现了_cmp_()方法,_cmp_用实例自身self和传入的实例 s 进行比较,如果 self 应该排在前面,就返回 -1,如果 s 应该排在前面,就返回1,如果两者相当,返回 0。

Student类实现了按name进行排序:

>>> L = [Student('Tim', 99), Student('Bob', 88), Student('Alice', 77)]>>> print sorted(L)[(Alice: 77), (Bob: 88), (Tim: 99)]
注意: 如果list不仅仅包含 Student 类,则 <code>\__cmp__</code> 可能会报错:L = [Student('Tim', 99), Student('Bob', 88), 100, 'Hello']print sorted(L)

python中 _len_

如果一个类表现得像一个list,要获取有多少个元素,就得用 len() 函数。

要让 len() 函数工作正常,类必须提供一个特殊方法_len_(),它返回元素的个数。

例如,我们写一个 Students 类,把名字传进去:

class Students(object):def __init__(self, *args):self.names = argsdef __len__(self):return len(self.names)

只要正确实现了_len_()方法,就可以用len()函数返回Students实例的“长度”:

>>> ss = Students('Bob', 'Alice', 'Tim')>>> print len(ss)3

任务:
斐波那契数列是由 0, 1, 1, 2, 3, 5, 8…构成。
请编写一个Fib类,Fib(10)表示数列的前10个元素,print Fib(10) 可以打印出数列的前 10 个元素,len(Fib(10))可以正确返回数列的个数10。
需要根据num计算出斐波那契数列的前N个元素。

参考代码:

class Fib(object):def __init__(self, num):a, b, L = 0, 1, []for n in range(num):L.append(a)a, b = b, a + bself.numbers = Ldef __str__(self):return str(self.numbers)__repr__ = __str__def __len__(self):return len(self.numbers)f = Fib(10)print fprint len(f)

python中数学运算

Python 提供的基本数据类型 int、float 可以做整数和浮点的四则运算以及乘方等运算。

但是,四则运算不局限于int和float,还可以是有理数、矩阵等。

要表示有理数,可以用一个Rational类来表示:

class Rational(object):def __init__(self, p, q):self.p = pself.q = q

p、q 都是整数,表示有理数 p/q。

如果要让Rational进行+运算,需要正确实现_add_

class Rational(object):def __init__(self, p, q):self.p = pself.q = qdef __add__(self, r):return Rational(self.p * r.q + self.q * r.p, self.q * r.q)def __str__(self):return '%s/%s' % (self.p, self.q)__repr__ = __str__

现在可以试试有理数加法:

>>> r1 = Rational(1, 3)>>> r2 = Rational(1, 2)>>> print r1 + r25/6

任务:
Rational类虽然可以做加法,但无法做减法、乘方和除法,请继续完善Rational类,实现四则运算。

提示:
减法运算:sub
乘法运算:mul
除法运算:div

如果运算结果是 6/8,在显示的时候需要归约到最简形式3/4。

参考代码:

def gcd(a, b):if b == 0:return areturn gcd(b, a % b)class Rational(object):def __init__(self, p, q):self.p = pself.q = qdef __add__(self, r):return Rational(self.p * r.q + self.q * r.p, self.q * r.q)def __sub__(self, r):return Rational(self.p * r.q - self.q * r.p, self.q * r.q)def __mul__(self, r):return Rational(self.p * r.p, self.q * r.q)def __div__(self, r):return Rational(self.p * r.q, self.q * r.p)def __str__(self):g = gcd(self.p, self.q)return '%s/%s' % (self.p / g, self.q / g)__repr__ = __str__r1 = Rational(1, 2)r2 = Rational(1, 4)print r1 + r2print r1 - r2print r1 * r2print r1 / r2

python中类型转换

Rational类实现了有理数运算,但是,如果要把结果转为 int 或 float 怎么办?

考察整数和浮点数的转换:

>>> int(12.34)12>>> float(12)12.0

如果要把 Rational 转为 int,应该使用:

r = Rational(12, 5)n = int(r)

要让int()函数正常工作,只需要实现特殊方法_int_():

class Rational(object):def __init__(self, p, q):self.p = pself.q = qdef __int__(self):return self.p // self.q

结果如下:

>>> print int(Rational(7, 2))3>>> print int(Rational(1, 3))0

同理,要让float()函数正常工作,只需要实现特殊方法_float_()

python中 @property

考察 Student 类:

class Student(object):def __init__(self, name, score):self.name = nameself.score = score

当我们想要修改一个 Student 的 scroe 属性时,可以这么写:

s = Student('Bob', 59)s.score = 60

但是也可以这么写:

s.score = 1000

显然,直接给属性赋值无法检查分数的有效性。

如果利用两个方法:

class Student(object):def __init__(self, name, score):self.name = nameself.__score = scoredef get_score(self):return self.__scoredef set_score(self, score):if score < 0 or score > 100:raise ValueError('invalid score')self.__score = score

这样一来,s.set_score(1000) 就会报错。

这种使用 get/set 方法来封装对一个属性的访问在许多面向对象编程的语言中都很常见。

但是写 s.get_score()s.set_score() 没有直接写 s.score 来得直接。

有没有两全其美的方法?----有。

因为Python支持高阶函数,在函数式编程中我们介绍了装饰器函数,可以用装饰器函数把 get/set 方法“装饰”成属性调用:

class Student(object):def __init__(self, name, score):self.name = nameself.__score = score@propertydef score(self):return self.__score@score.setterdef score(self, score):if score < 0 or score > 100:raise ValueError('invalid score')self.__score = score

注意: 第一个score(self)是get方法,用@property装饰,第二个score(self, score)是set方法,用@score.setter装饰,@score.setter是前一个@property装饰后的副产品。

现在,就可以像使用属性一样设置score了:

>>> s = Student('Bob', 59)>>> s.score = 60>>> print s.score60>>> s.score = 1000Traceback (most recent call last):...ValueError: invalid score

说明对 score 赋值实际调用的是 set方法。

python中 _slots_

由于Python是动态语言,任何实例在运行期都可以动态地添加属性。

如果要限制添加的属性,例如,Student类只允许添加 name、gender和score 这3个属性,就可以利用Python的一个特殊的_slots_来实现。

顾名思义,_slots_是指一个类允许的属性列表:

class Student(object):__slots__ = ('name', 'gender', 'score')def __init__(self, name, gender, score):self.name = nameself.gender = genderself.score = score

现在,对实例进行操作:

>>> s = Student('Bob', 'male', 59)>>> s.name = 'Tim' # OK>>> s.score = 99 # OK>>> s.grade = 'A'Traceback (most recent call last):...AttributeError: 'Student' object has no attribute 'grade'

_slots_的目的是限制当前类所能拥有的属性,如果不需要添加任意动态的属性,使用_slots_也能节省内存。

python中 _call_

在Python中,函数其实是一个对象:

>>> f = abs>>> f.__name__'abs'>>> f(-123)123

由于 f 可以被调用,所以,f 被称为可调用对象。

所有的函数都是可调用对象。

一个类实例也可以变成一个可调用对象,只需要实现一个特殊方法_call_()

我们把 Person 类变成一个可调用对象:

class Person(object):def __init__(self, name, gender):self.name = nameself.gender = genderdef __call__(self, friend):print 'My name is %s...' % self.nameprint 'My friend is %s...' % friend

现在可以对 Person 实例直接调用:

>>> p = Person('Bob', 'male')>>> p('Tim')My name is Bob...My friend is Tim...

单看 p(‘Tim’) 你无法确定 p 是一个函数还是一个类实例,所以,在Python中,函数也是对象,对象和函数的区别并不显著。

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

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

相关文章

Hello,Spider!入门第一个爬虫程序

在各大编程语言中&#xff0c;初学者要学会编写的第一个简单程序一般就是“Hello, World!”&#xff0c;即通过程序来在屏幕上输出一行“Hello, World!”这样的文字&#xff0c;在Python中&#xff0c;只需一行代码就可以做到。我们把这第一个爬虫就称之为“HelloSpider”&…

【Git】Github 上commit后,绿格子contribution却不显示?不知道怎么弥补?解决方法在这里

github 上commit后&#xff0c;绿格子&#xff08;contribution&#xff09;却不显示 问题描述 今天一直在github上面commit代码&#xff0c;但是github中并没有显示自己的contribution&#xff08;没有绿色的格子&#xff09;&#xff0c;全是空白&#xff0c;网上一查是因为…

免费分享一套SpringBoot+Vue自习室(预约)管理系统,帅呆了~~

大家好&#xff0c;我是java1234_小锋老师&#xff0c;看到一个不错的SpringBootVue自习室预约)管理系统&#xff0c;分享下哈。 项目视频演示 【免费】SpringBootVue自习室预约(预约)管理系统 Java毕业设计_哔哩哔哩_bilibili【免费】SpringBootVue自习室预约(预约)管理系统…

Java项目企业设备管理系统

java项目企业设备管理系统javaweb项目ssm框架项目 运行环境:idea/eclipse tomcat jdk mysql navicat 系统用户分为员工和管理员两类用户。两类用户都可以进行系统的登录&#xff0c;虽然进入的系统主页结构相似&#xff0c;但是在功能上有不同。员工的密码可以自己进入系统后…

【目标检测-数据集准备】DIOR转为yolo训练所需格式

【目标检测】DIOR遥感影像数据集&#xff0c;转为yolo系列模型训练所需格式。 标签文件位于Annotations下&#xff0c;格式为xml&#xff0c;yolo系列模型训练所需格式为txt&#xff0c;格式为 class_id x_center,y_center,w,h其中&#xff0c;train&#xff0c;text&#xff…

Python笔记|字符串的转义

重新梳理一遍python的基础知识 除了数字&#xff0c;Python 还可以操作字符串。字符串有多种表现形式&#xff0c;用单引号&#xff08;……&#xff09;或双引号&#xff08;"……"&#xff09;标注的结果相同 。反斜杠 \ 用于转义&#xff1a; >>>spam e…

java抽象类的作用及解析

在 Java 中&#xff0c;抽象类是一种特殊的类&#xff0c;它可以用于定义一些抽象的方法和属性&#xff0c;这些方法和属性可能在子类中有不同的实现。 抽象类的主要作用包括&#xff1a; 提供抽象方法&#xff1a;抽象类可以包含一些没有具体实现的抽象方法&#xff0c;这些…

JVM-5

1.选择垃圾收集器 如果你的堆大小不是很大&#xff08;比如 100MB &#xff09;&#xff0c;选择串行收集器一般是效率最高的。 参数&#xff1a; -XX:UseSerialGC 。如果你的应用运行在单核的机器上&#xff0c;或者你的虚拟机核数只有单核&#xff0c;选择串行收集器依然是合…

论文阅读:FCB-SwinV2 Transformer for Polyp Segmentation

这是对FCBFormer的改进&#xff0c;我的关于FCBFormer的论文阅读笔记&#xff1a;论文阅读FCN-Transformer Feature Fusion for PolypSegmentation-CSDN博客 1&#xff0c;整体结构 依然是一个双分支结构&#xff0c;总体结构如下&#xff1a; 其中一个是全卷积分支&#xff…

数据结构之链式二叉树

当我们初步了解二叉树后 我们就可以进一步去深入学习二叉树了 1.链式二叉树的遍历 这里我们先去定义链式二叉树的结构 分为两个指针 一左一右 他们分别指向左子树和右子树 typedef int BTDataType;typedef struct BinaryTreeNode {BTDataType data;struct BinartTreeNod…

【设计模式】一、设计模式概述

文章目录 一、设计模式概述&#xff08;一&#xff09;设计模式是什么1. 设计模式的定义2. 设计模式的组成要素3、常用设计模式一览表 &#xff08;二&#xff09;设计模式的优点&#xff08;用途&#xff09;※ 本文小结 一、设计模式概述 &#xff08;一&#xff09;设计模式…

tcp/ip协议2实现的插图,数据结构8 (30 - 32章)

(201) 201 三十0 中断优先级补充 (202) 202 三十1 TCP的用户需求 函tcp_usrreq一 (203) 203 三十2 TCP的用户需求 函tcp_usrreq二 (204) 204 三十3 TCP的用户需求 函tcp_usrreq三 (205) 205 三十4 TCP的用户需求 函tcp_usrreq四 (206) 206 三十5 TCP的用户需求 函tcp_usrreq五 …

docker实战(3)

1, jdk17版本的dockerfile FROM eclipse-temurin:17-jre ADD ./target/ods-poc-0.0.1-SNAPSHOT.jar /home/app/app.jar WORKDIR /home/app ENV TZ Asia/Shanghai ENTRYPOINT ["java","-jar","/home/app/app.jar"] EXPOSE 8083dockerfile 1, …

emment语法

文章目录 1. 生成普通的标签2. 生成 div类名3. 生成指定标签类名/id 值4. 生成带有子元素的标签5. 生成内部文本6. 一次可以生成多个标签7. 生成带有指定属性 的元素8. 生成相邻兄弟元素 1. 生成普通的标签 本质使用的就是元素选择器&#xff0c;例如 div p a 标签等等。 2. …

Openlayers入门教程 --- 万字长篇

也许你还不熟悉Openlayers&#xff0c;也许你是一个Openlayers小白&#xff0c;零基础没关系&#xff0c;这篇文章提供最基础的 Openlayers 教程&#xff0c;简单易学&#xff0c;贯穿整个Openlayers 知识体系。读完本文&#xff0c;您将会对 Openlayers 有一个全新的认识。 文…

图像分类技术在电商平台的创新应用与实践

一、引言 在当今快速发展的互联网电商领域&#xff0c;商家面临着激烈的竞争和不断变化的市场需求。我们在服务电商的过程中&#xff0c;利用AI大模型技术创新性地引入了图像分类技术&#xff0c;为供应链管理带来了革命性的变革。接下来&#xff0c;我们将深入探讨这一项目的…

51单片机基础篇系列-超声波测距

&#x1f308;个人主页&#xff1a;会编辑的果子君 &#x1f4ab;个人格言:“成为自己未来的主人~” HC-SR04产品特点 典型工作用电压&#xff1a;5V 超小静态工作电流&#xff1a;小于2mA 感应角度&#xff1a;不大于15度 探测距离&#xff1a;2cm-400cm 高精度&#…

论文阅读:LAPFormer: A Light and Accurate PolypSegmentation Transformer

这是一个基于Transformer的轻量级图像分割模型。作者们使用MiT&#xff08;Mix Transformer&#xff09;作为编码器&#xff0c;并为LAPFormer设计了一个新颖的解码器&#xff0c;该解码器利用多尺度特征&#xff0c;并包含特征精炼模块和特征选择模块&#xff0c;以生成精细的…

16. UE5 RPG获取GE应用的回调,并根据Tag设置数据显示到窗口

在上一篇介绍了对标签如何在项目中设置&#xff0c;这一篇先讲解一下如何在GE里面使用GameplayTag标签。 之前我在第十一章节中 11. UE5 RPG使用GameplayEffect修改角色属性&#xff08;二&#xff09;介绍了一些GE的属性&#xff0c;在UE 5.3版本中&#xff0c;修改的配置方式…

药店在线客服机器人的设计与开发

摘要 随着信息技术的快速发展和人工智能领域的不断进步&#xff0c;药店在线客服机器人已经成为现代药店服务模式中不可或缺的一部分&#xff0c;这种机器人技术通过模拟人类客服代表&#xff0c;能够提供24/7的咨询服务&#xff0c;从而大幅提高服务效率和顾客满意度&#xff…