【Python学习笔记】第十九节 Python 面向对象(一)

news2024/11/17 5:52:10

在现实世界中,随处可见的一种事物就是对象,对象是事物存在的实体,如学生、汽车等。人类解决问题的方式总是将复杂的事物简单化,于是就会思考这些对象都是由哪些部分组成的。通常都会将对象划分为两个部分,即静态部分与动态部分。

顾名思义,静态部分就是不能动的部分,这个部分被称为“属性”,任何对象都会具备其自身属性,如一个人,其属性包括高矮、胖瘦、年龄、性别等。然而具有这些属性的人会执行哪些动作也是一个值得探讨的部分,这个人可以转身、微笑、说话、奔跑,这些是这个人具备的行为(动态部分),人类通过探讨对象的属性和观察对象的行为来了解对象。

Python从设计之初就已经是一门面向对象的语言,正因为如此,在Python中创建一个类和对象是很容易的。本章节我们将详细介绍Python的面向对象编程。


一、面向对象简介

  • 类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。

  • 类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。

  • 数据成员:类变量或者实例变量, 用于处理类及其实例对象的相关的数据。

  • 方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。

  • 局部变量:定义在方法中的变量,只作用于当前实例的类。

  • 实例变量:在类的声明中,属性是用变量来表示的。这种变量就称为实例变量,是在类声明的内部但是在类的其他成员方法之外声明的。

  • 继承:即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。例如,有这样一个设计:一个Dog类型的对象派生自Animal类,这是模拟"是一个(is-a)"关系(例图,Dog是一个Animal)。

  • 实例化:创建一个类的实例,类的具体对象。

  • 方法:类中定义的函数。

  • 对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。

二、创建类

Python使用class关键字来定义类,其语法格式如下:

class ClassName:
   '类的帮助信息'   #类文档字符串
   class_suite  #类体
  • 类的帮助信息可以通过ClassName.__doc__查看。

  • class_suite 由类成员,方法,数据属性组成。

以下是一个简单的 Python 类的例子:

# coding=utf-8

class Cat:
    #属性
    age = 1
    #方法
    def eat(self):
        print("猫在吃鱼....")

    def drink(self):
        print("猫正在喝.....")

    def sleep(self):
        print("猫在睡觉.....")
  • age 变量是一个类变量,它的值将在这个类的所有实例之间共享。你可以在内部类或外部类使用 Cat.age 访问。

  • self 代表类的实例,self 在定义类的方法时是必须有的,虽然在调用时不必传入相应的参数。

self代表类的实例,而非类

类的方法与普通的函数只有一个特别的区别——它们必须有一个额外的第一个参数名称, 按照惯例它的名称是 self。

# coding=utf-8

class Cat:
    # 属性
    weight = 1.0

    # 方法
    def eat(self):
        print("猫在吃鱼....")

    def drink(self):
        print("猫正在喝.....")

    def sleep(self):
        print("猫在睡觉.....")

    def prt(me):
        print(me)
        print(me.__class__)


cat = Cat()
cat.prt();

执行结果为:

从执行结果可以看出,self 代表的是类的实例,代表当前对象的地址,而 self.__class__ 则指向类。

self 不是 python 关键字,我们把他换成 me 也是可以正常执行的:

# coding=utf-8

class Cat:
    # 属性
    weight = 1.0

    # 方法
    def eat(self):
        print("猫在吃鱼....")

    def drink(self):
        print("猫正在喝.....")

    def sleep(self):
        print("猫在睡觉.....")

    def prt(me):
        print(me)
        print(me.__class__)


cat = Cat()
cat.prt();

三、创建实例对象

实例化类其他编程语言中一般用关键字 new,但是在 Python 中并没有这个关键字,类的实例化类似函数调用方式。

# coding=utf-8

class Cat:
    # 属性
    weight = 1.0

    # 方法
    def eat(self):
        print("猫在吃鱼....")

    def drink(self):
        print("猫正在喝.....")

    def sleep(self):
        print("猫在睡觉.....")


# 创建一个对象
tom = Cat()

1、调用对象的方法

# coding=utf-8

class Cat:
    # 属性
    weight = 1.0

    # 方法
    def eat(self):
        print("猫在吃鱼....")

    def drink(self):
        print("猫正在喝.....")

    def sleep(self):
        print("猫在睡觉.....")


# 创建一个对象
tom = Cat()

# 调用对象的方法
tom.eat()
tom.drink()

2、添加属性

# coding=utf-8

class Cat:
    # 属性
    weight = 1.0

    # 方法
    def eat(self):
        print("猫在吃鱼....")

    def drink(self):
        print("猫正在喝.....")

    def sleep(self):
        print("猫在睡觉.....")


# 创建一个对象
tom = Cat()

# 调用对象的方法
tom.eat()
tom.drink()

# 添加属性
tom.name = "汤姆"
tom.age = 40

3、获取对象的属性

# coding=utf-8

class Cat:
    # 属性
    weight = 1.0

    # 方法
    def eat(self):
        print("猫在吃鱼....")

    def drink(self):
        print("猫正在喝.....")

    def sleep(self):
        print("猫在睡觉.....")

    def introduce(self):
        print("%s的年龄是:%d" % (tom.name, tom.age))


# 创建一个对象
tom = Cat()

# 调用对象的方法
tom.eat()
tom.drink()

# 添加属性
# 给tom指向的对象添加2个属性
tom.name = "汤姆"
tom.age = 40

# 获取属性的第1种方式
# print("%s的年龄是:%d"%(tom.name, tom.age))

tom.introduce()

也可以使用以下函数的方式来访问属性:

  • getattr(obj, name[, default]) : 访问对象的属性。

  • hasattr(obj,name) : 检查是否存在一个属性。

  • setattr(obj,name,value) : 设置一个属性。如果属性不存在,会创建一个新属性。

  • delattr(obj, name) : 删除属性。

hasattr(tom, 'age')  # 如果存在 'age' 属性返回 True。
getattr(tom, 'age')  # 返回 'age' 属性的值
setattr(tom, 'age', 8)  # 添加属性 'age' 值为 8
delattr(tom, 'age')  # 删除属性 'age'

4、__init__()方法

是一种特殊的方法,被称为类的构造函数或初始化方法,当创建了这个类的实例时就会调用该方法

# coding=utf-8

class Cat:
    # 属性
    weight = 1.0

    # 初始化对象
    def __init__(self, new_name, new_age):
        self.name = new_name
        self.age = new_age

    def __str__(self):
        return "%s的年龄是:%d" % (self.name, self.age)

    # 方法
    def eat(self):
        print("猫在吃鱼....")

    def drink(self):
        print("猫正在喝.....")

    def sleep(self):
        print("猫在睡觉.....")

    def introduce(self):
        print("%s的年龄是:%d" % (self.name, self.age))


# 创建一个对象
tom = Cat("汤姆", 40)
tom.eat()
tom.drink()
# tom.name = "汤姆"
# tom.age = 40
tom.introduce()

baimao = Cat("白猫", 10)
# baimao.name = "白猫"
# baimao.age = 10
baimao.introduce()

5、__str__方法

用于将值转化为适于人阅读的形式

# coding=utf-8

class Cat:
    # 属性
    weight = 1.0

    # 初始化对象
    def __init__(self, new_name, new_age):
        self.name = new_name
        self.age = new_age

    def __str__(self):
        return "%s的年龄是:%d" % (self.name, self.age)

    # 方法
    def eat(self):
        print("猫在吃鱼....")

    def drink(self):
        print("猫正在喝.....")

    def sleep(self):
        print("猫在睡觉.....")

    def introduce(self):
        print("%s的年龄是:%d" % (self.name, self.age))


# 创建一个对象
tom = Cat("汤姆", 40)
tom.eat()
tom.drink()
# tom.name = "汤姆"
# tom.age = 40
tom.introduce()

baimao = Cat("白猫", 10)
# baimao.name = "白猫"
# baimao.age = 10
baimao.introduce()

print(tom)
print(baimao)

四、Python内置类属性

  • __dict__ : 类的属性(包含一个字典,由类的数据属性组成)

  • __doc__ :类的文档字符串

  • __name__: 类名

  • __module__: 类定义所在的模块(类的全名是'__main__.className',如果类位于一个导入模块mymod中,那么className.__module__ 等于 mymod)

  • __bases__ : 类的所有父类构成元素(包含了一个由所有父类组成的元组)

# coding=utf-8

class Cat:
    # 属性
    weight = 1.0

    # 初始化对象
    def __init__(self, new_name, new_age):
        self.name = new_name
        self.age = new_age

    def __str__(self):
        return "%s的年龄是:%d" % (self.name, self.age)

    # 方法
    def eat(self):
        print("猫在吃鱼....")

    def drink(self):
        print("猫正在喝.....")

    def sleep(self):
        print("猫在睡觉.....")

    def introduce(self):
        print("%s的年龄是:%d" % (self.name, self.age))


# 创建一个对象
tom = Cat("汤姆", 40)
tom.eat()
tom.drink()
# tom.name = "汤姆"
# tom.age = 40
tom.introduce()

baimao = Cat("白猫", 10)
# baimao.name = "白猫"
# baimao.age = 10
baimao.introduce()

print(tom)
print(baimao)


print("Cat.__doc__:", Cat.__doc__)
print("Cat.__name__:", Cat.__name__)
print("Cat.__module__:", Cat.__module__)
print("Cat.__bases__:", Cat.__bases__)
print("Cat.__dict__:", Cat.__dict__)

五、python对象销毁(垃圾回收)

Python 使用了引用计数这一简单技术来跟踪和回收垃圾。

在 Python 内部记录着所有使用中的对象各有多少引用。一个内部跟踪变量,称为一个引用计数器。

当对象被创建时, 就创建了一个引用计数, 当这个对象不再需要时, 也就是说, 这个对象的引用计数变为0 时, 它被垃圾回收。但是回收不是"立即"的, 由解释器在适当的时机,将垃圾对象占用的内存空间回收。

析构函数 __del__ ,__del__在对象销毁的时候被调用,当对象不再被使用时,__del__方法运行:

# coding=utf-8

class Dog:

    def __del__(self):
        print("-----英雄over------")


dog1 = Dog()
dog2 = dog1

del dog1  # 不会调用 __del__方法,因为这个对象 还有其他的变量指向它,即 引用计算不是0
del dog2  # 此时会调用__del__方法,因为没有变量指向它了
print("====================")

# 如果在程序结束时,有些对象还存在,那么python解释器会自动调用它们的__del__方法来完成清理工作

六、类的继承

面向对象的编程带来的主要好处之一是代码的重用,实现这种重用的方法之一是通过继承机制。

通过继承创建的新类称为子类派生类,被继承的类称为基类父类超类

继承语法

class 派生类名(基类名)
    ...

在python中继承中的一些特点:

  • 1、如果在子类中需要父类的构造方法就需要显式的调用父类的构造方法,或者不重写父类的构造方法。详细说明可查看: python 子类继承父类构造函数说明。

  • 2、在调用基类的方法时,需要加上基类的类名前缀,且需要带上 self 参数变量。区别在于类中调用普通函数时并不需要带上 self 参数

  • 3、Python 总是首先查找对应类型的方法,如果它不能在派生类中找到对应的方法,它才开始到基类中逐个查找。(先在本类中查找调用的方法,找不到才去基类中找)。

如果在继承元组中列了一个以上的类,那么它就被称作"多重继承" 。

语法:

派生类的声明,与他们的父类类似,继承的基类列表跟在类名之后,如下所示:

class SubClassName (ParentClass1[, ParentClass2, ...]):
    ...
# coding=utf-8

class Animal:

    def __init__(self):
        print("调用父类构造函数")

    def eat(self):
        print("-----吃----")

    def drink(self):
        print("-----喝----")

    def sleep(self):
        print("-----睡觉----")

    def run(self):
        print("-----跑----")


class Dog(Animal):
    def __init__(self):
        print("调用子类构造函数")

    """
    def eat(self):
        print("-----吃----")
    def drink(self):
        print("-----喝----")
    def sleep(self):
        print("-----睡觉----")
    def run(self):
        print("-----跑----")
    """

    def bark(self):
        print("----汪汪叫---")


class Cat(Animal):
    def catch(self):
        print("----抓老鼠----")


# a = Animal()
# a.eat()

wangcai = Dog()
wangcai.eat()

tom = Cat()
tom.eat()

继承多个类

class Base(object):
    def test(self):
        print("----Base")

class A(Base):
    def test1(self):
        print("-----test1")

class B(Base):
    def test2(self):
        print("-----test2")

class C(A,B):
    pass


c = C()
c.test1()
c.test2()
c.test()

可以使用issubclass()或者isinstance()方法来检测。

  • issubclass() - 布尔函数判断一个类是另一个类的子类或者子孙类,语法:issubclass(sub,sup)

  • isinstance(obj, Class) 布尔函数如果obj是Class类的实例对象或者是一个Class子类的实例对象则返回true。

七、方法重写

如果你的父类方法的功能不能满足你的需求,你可以在子类重写你父类的方法:

# coding=utf-8

class Animal:
    def eat(self):
        print("-----吃----")
    def drink(self):
        print("-----喝----")
    def sleep(self):
        print("-----睡觉----")
    def run(self):
        print("-----跑----")

class Dog(Animal):
    def bark(self):
        print("----汪汪叫---")


class Xiaotq(Dog):
    def fly(self):
        print("----飞----")

    def bark(self):
        print("----狂叫-----")


xiaotq = Xiaotq()
xiaotq.fly()
xiaotq.bark()
xiaotq.eat()

1、基础重载方法

下表列出了一些通用的功能,你可以在自己的类重写:

序号

方法, 描述 & 简单的调用

1

__init__ ( self [,args...] ) 构造函数,简单的调用方法: obj = className(args)

2

__del__( self ) 析构方法, 删除一个对象,简单的调用方法 : del obj

3

__repr__( self ) 转化为供解释器读取的形式,简单的调用方法 : repr(obj)

4

__str__( self ) 用于将值转化为适于人阅读的形式,简单的调用方法 : str(obj)

5

__cmp__ ( self, x ) 对象比较 ,简单的调用方法 : cmp(obj, x)

2、运算符重载

Python同样支持运算符重载,实例如下:

# coding=utf-8

class Vector:
    def __init__(self, a, b):
        self.a = a
        self.b = b

    def __str__(self):
        return 'Vector (%d, %d)' % (self.a, self.b)

    def __add__(self, other):
        return Vector(self.a + other.a, self.b + other.b)


v1 = Vector(2, 10)
v2 = Vector(5, -2)
print(v1 + v2)

八、类属性与方法

1、类的私有属性

__private_attrs:两个下划线开头,声明该属性为私有,不能在类的外部被使用或直接访问。在类内部的方法中使用时 self.__private_attrs

2、类的方法

在类的内部,使用 def 关键字可以为类定义一个方法,与一般函数定义不同,类方法必须包含参数 self,且为第一个参数

3、类的私有方法

__private_method:两个下划线开头,声明该方法为私有方法,不能在类的外部调用。在类的内部调用 self.__private_methods

# coding=utf-8

class Dog:
    __age = 0
    name = ""

    def __init__(self, new_name):
        self.name = new_name
        self.__age = 0  # 定义了一个私有的属性,属性的名字是__age

    def set_age(self, new_age):
        if new_age > 0 and new_age <= 100:
            self.__age = new_age
        else:
            self.__age = 0

    def get_age(self):
        return self.__age


dog = Dog("小白")
# dog.age = -10
# dog.name = "小白"

# print(dog.age)


dog.set_age(10)
age = dog.get_age()
print(age)

# dog.get_name()

# dog.__age = -10
# print(dog.__age)  # 报错,实例不能访问私有变量

# object._className__attrName( 对象名._类名__私有属性名 )访问属性
print(dog._Dog__age)

九、单下划线、双下划线、头尾双下划线说明:

  • __foo__: 定义的是特殊方法,一般是系统定义名字 ,类似 __init__() 之类的。

  • _foo: 以单下划线开头的表示的是 protected 类型的变量,即保护类型只能允许其本身与子类进行访问,不能用于 from module import *

  • __foo: 双下划线的表示的是私有类型(private)的变量, 只能是允许这个类本身进行访问了。

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

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

相关文章

一文让你上手shell

简介shell是C 语言编写的程序&#xff0c;是向操作访问Linux内核的桥梁。shell也是测试人员需要简单必备的一项小技能&#xff0c;至少能看懂并简单编写脚本&#xff0c;可以让与Linux相关的操作提升1个level。扩展名&#xff1a;.sh运行操作系统&#xff1a;Linux运行环境&…

cesium从入门到进阶(一):坐标系与坐标系转换

目录 一、坐标系 1、屏幕坐标系(像素) 1.1 二维笛卡尔平面坐标Cartesian2 1.2 三维笛卡尔空间坐标(世界坐标)Cartesian3 2、地理坐标系 2.1 地理坐标系&#xff08;弧度&#xff09;Cartographic 2.2 地理坐标系&#xff08;经纬度&#xff09;WGS84 二、坐标系转换 1…

华为不丢失数据解手机屏幕锁华为售后能保资料解锁吗华为锁屏保留数据荣耀手机解锁保数据华为手机保存数据解锁

大家好&#xff0c;今天给大家分享的华为mate9手机忘记密码保资料不清除数据解锁华为手机案例分享&#xff1a;这个用户是从马来西亚邮递回国的华为p30手机进行保资料不清除数据解除华为锁屏密码&#xff0c;由于机主突然的去世&#xff0c;手机里有公司贵重的资料&#xff0c;…

27 openEuler管理网络-通过ifcfg文件配置网络

文章目录27 openEuler管理网络-通过ifcfg文件配置网络27.1 配置静态网络27.2 配置动态网络27.3 配置默认网关27 openEuler管理网络-通过ifcfg文件配置网络 说明&#xff1a; 通过ifcfg文件配置的网络配置不会立即生效&#xff0c;需要在root权限下执行systemctl reload Network…

因为需求理解不到位,视频自动播放列表又重写了

一、一定要理解需求再下手 刚接手一个旧项目&#xff0c;只需要在上面添加一些新功能&#xff0c;和后端对对接口就可以了。因为害怕总是去问别人需求惹人烦&#xff0c;所以好几次讨论给我讲需求我就说我懂了&#xff0c;然后下来自己思考怎么做。最后又因为好多需求理解不到…

【机器学习】机器学习实验一:线性回归(详细代码展示)

文章目录一、前言二、梯度下降理解算法2.1 单变量线性回归2.2 多变量线性回归2.3 正则化2.3.1 L2正则化&#xff08;Ridge回归&#xff09;2.3.2 L1正则化&#xff08;Lasso回归&#xff09;三、实验一详细代码案例一、前言 本次实验我将分为两个部分进行讲解&#xff0c;第一…

Echarts 模拟汽车速度和油量的仪表显示,两个仪表盘同图

第025个点击查看专栏目录本示例的目标是模拟汽车速度和油量的仪表显示&#xff0c;这里两个仪表盘同图&#xff0c;并倾斜一定的角度。 文章目录示例效果示例源代码&#xff08;共115行&#xff09;相关资料参考专栏介绍示例效果 示例源代码&#xff08;共115行&#xff09; /*…

ABAP中Literals的用法(untyped literal vs. typed literal)

1. 什么是Literals ? Literals的字面意思即“文字”。其实&#xff0c;Literals就是在ABAP代码中直接指定的一个字符串&#xff0c;但注意哦&#xff0c;这个字符串并不意味着其类型一定是string哦。 要弄清这个概念&#xff0c;就要清楚ABAP对于Literals 的定义和处理方式。…

Win10+vs2019配置与运行RenderMatch+用contextcapture进行重建

Win10vs2019配置与运行RenderMatch用contextcapture进行重建 继上一篇博客&#xff0c;ground image 和aerial image影像匹配结果将会被保存为match.bin二进制文件里 再次运行时&#xff0c;只需要把这个bin文件load进来就可以了&#xff0c;不需要再次进行匹配&#xff0c;修…

推荐五款在手机上写代码的APP(附下载地址)

&#x1f31f;1.C4droid一款Android设备上的C/C程序IDE&#x1f31f;2.AIDE一个直接在 Android 设备上开发 Android 应用的集成开发环境基于原版深度定制、适配本土化的操作习惯&#xff0c;一键快速添加常用的代码&#xff0c;大幅提高开发效率。实时的语言翻译&#xff0c;帮…

CUDA的卸载

大家好,下面将进行CUDA的卸载,卸载情况描述如下: > 安装在电脑Windows10系统 (1)安装在电脑Windows10系统,打开控制面板-程序-程序和功能,可以看到自己已经安装过的CUDA,如下所示: (2)依次选中需要卸载的CUDA包,鼠标右键点击卸载即可,一般需要保留3个已经安装…

idea集成Alibaba Cloud Toolkit插件

idea集成Alibaba Cloud Toolkit插件 ​ 使用该插件主要是简化打包、上传、启动服务的相关操作。 ​ 很早之前的方式是使用开发工具&#xff08;eclipse,idea&#xff09;&#xff0c;使用maven命令完成项目打包&#xff08;这里指jar&#xff09;&#xff0c;然后通过shell工…

SSL证书的五大优势

SSL 重要吗&#xff1f;我需要 SSL 吗&#xff1f;开车时需要系好安全带吗&#xff1f;看日食时需要戴防护眼镜吗&#xff1f;就前三个问题而言&#xff0c;答案是一个很大的“是”&#xff01;如果您在 2021 年拥有网站或博客&#xff0c;则需要 SSL。就这么简单。SSL 证书不再…

BigBird:大鸟模型中文生成式长文本摘要实践

1、介绍 BigBird 是一种基于稀疏注意力的Transformer&#xff0c;可将基于Transformer的模型&#xff08;例如 BERT&#xff09;扩展到更长的序列。 论文&#xff1a;https://arxiv.org/abs/2007.14062 代码&#xff1a;https://github.com/google-research/bigbird BigBir…

Day902.Memory存储引擎 -MySQL实战

Memory存储引擎 Hi&#xff0c;我是阿昌&#xff0c;今天学习记录的是关于Memory存储引擎的内容。 两个 group by 语句都用了 order by null&#xff0c;为什么使用内存临时表得到的语句结果里&#xff0c;0 这个值在最后一行&#xff1b; 而使用磁盘临时表得到的结果里&…

ARM的工作模式和37个寄存器

一、ARM的工作模式 ARM一共有7种工作模式 模式含义User非特权模式&#xff0c;大部分任务执行在这种模式FIQ当一个高优先级&#xff08;fast) 中断产生时将会进入这种模式IRQ当一个低优先级&#xff08;normal) 中断产生时将会进入这种模式Supervisor当复位或软中断指令执行时…

巨头混战,抢着“兜底”自动驾驶安全

诚然&#xff0c;中国汽车行业的发展绝对不会拘泥于电动化&#xff0c;必定会在电动化的基础上&#xff0c;迎接下半场的快速智能化。 2021年6月&#xff0c;长城汽车线控底盘全球首次发布。 彼时&#xff0c;长城汽车技术副总裁宋东先宣布&#xff0c;整合了线控转向、线控制…

基于海鸥算法改进的DELM分类-附代码

海鸥算法改进的深度极限学习机DELM的分类 文章目录海鸥算法改进的深度极限学习机DELM的分类1.ELM原理2.深度极限学习机&#xff08;DELM&#xff09;原理3.海鸥算法4.海鸥算法改进DELM5.实验结果6.参考文献7.Matlab代码1.ELM原理 ELM基础原理请参考&#xff1a;https://blog.c…

【数据结构与算法】单链表的增删查改(附源码)

这么可爱的猫猫不值得点个赞吗&#x1f63d;&#x1f63b; 目录 一.链表的概念和结构 二.单链表的逻辑结构和物理结构 1.逻辑结构 2.物理结构 三.结构体的定义 四.增加 1.尾插 SListpushback 2.头插 SListpushfront 五.删除 1.尾删 SListpopback 2.头删 SListpo…

浅谈音视频开发,如何更好的去学习?

Android音视频跟普通的应用层开发相比&#xff0c;的确更花费精力。期间为了学习音视频的录制&#xff0c;编码&#xff0c;处理也看过大大小小的几十个项目。总体感觉就是知识比较零散&#xff0c;对刚入门的朋友比较不友好。所以才萌生了整理一个Android音视频学习路线的想法…