Python中的type和object详解

news2024/11/18 15:25:45

这篇博客主要描述Python的新风格对象(new-style objects),如下:

  1. <type 'type'>和<type 'object'>分别是什么?
  2. 用户自定义的类和实例之间是怎么联系的?它们和内置类型又是怎么联系的?
  3. 什么是元类(metaclasses)?

New-style表明这篇博客所说的内容只适用于版本为2.2及以上的python。


开始之前

最主要,是理解type和object的区别与联系。我们平时用的最多的是Object,比如你定义一个类时,会继承object:

>>> class Test(object):
...     pass

这里你定义了一个自定义类Test,不难看出,Test继承了object,也就是说,objectTest的超类(或者说基类)。
接下来,你可以再定义一个类:

>>> class subTest(Test):
...     pass

subTest继承了Test,同时,因为Test继承了object,所以也可以说subTest继承了object。在这里涉及到一个重要的知识点,那就是继承具有传递性。如果你仔细观察,你会发现另外一个知识点,那就是:object是所有类的超类(这句话至关重要)。那type是什么呢?它是object的类型(也就是说object是type的实例),同时,object又是type的超类。

type是object的类型,同时,object又是type的超类”这句话看起来就充满疑点:那到底是先有object还是先有type呢?其实,“先有object和还是type问题”就像“先有鸡还是先有蛋问题”。到底先有谁呢?不急,请继续看:

你要明白这些,先要知道,python是面向对象的语言。在python里面,一切皆为对象

一切皆为对象?这里对于一部分人来说,可能不是很容易理解。这么说吧,在python里,int整形是对象,整数2也是对象,你定义的函数啊,类啊都是对象,你定义的变量也是对象。总之,你在python里能用到的都可以称之为对象。

好了,把python里一切皆为对象给整明白后,你要明白在面向对象的体系中,存在两种关系:

  • 父子关系(图中以实线描述):这种关系存在于某个类(subclass)是另一个类(superclass)的特别版本之中。通常描述为“子类是一种父类”。比如:蛇是一种爬行动物(Snake is a kind of reptile)。其中,蛇(snake)是子类,爬行动物(reptile)是父类。蛇拥有爬行动物的特征,同时,又拥有标志自己是一条蛇的特征。
  • 类型实例关系(图中以虚线描述):这种关系存在于两个对象之中,其中一个对象(实例)是另一个对象(类型)的具体实现。我有一条宠物蛇叫Squasher,那么Squasher就是蛇的一个实例。英文描述为:"Squasher is an instance of snake".

用实线表示父子关系,是因为父与子的关系更加“贴实”。比如有人叫你列出有关蛇的词,你可能会说蛇是爬行动物,但你不会说出蛇是Squasher....
我想如果把上面的两种关系用代码表示出来你会更加直观:

>>> class reptile(object):
...     feature = "有标志自己是爬行动物的特征"
...     name = "爬行动物"
...
>>> class snake(reptile):
...     snake_feature = "除了有标志自己是爬行动物特征,还有自己是蛇的特征"
...     name = "蛇"
...
>>> Squasher = snake()

class reptile(object)class snake(reptile)就是代表父子关系。object是reptile的基类,reptile是snake的超类(基类)。这里有没有想起来 object是所有类的超类
Squasher = snake()是类型实例关系。将类snake实例化就得到了Squasher。

这时候,有两条很有用的规则:

  1. Dashed Arrow Up Rule:If X is an instance of A, and A is a subclass of B, then X is an instance of B as well.翻译过来应该是“虚线向上规则”:如果X是A的实例,同时A又是B的子类,那么,X也是B的实例。
  2. Dashed Arrow Down Rule:If B is an instance of M, and A is a subclass of B, then A is an instance of M as well.翻译过来应该是“虚线向下规则”:如果B是M的实例,同时A是B的子类,那么,A也是M的实例。其实这条规则很少会用到,但却和这篇博客要讲的内容息息相关。我来略作分析,从“如果B是M的实例”这句话得出,B是实例,“A是B的子类” --> B是一个(父)。B是实例,同时又是一个类?怎么回事?看完这篇博客,你会知道答案的。

在这里,我来解释一下为什么叫"虚线向上规则",通过观察上图右边,我们可以清晰地见到一个带箭头的虚线,从X端出发,射向A端,此时,A端为箭头端,虚线代表类型实例关系,所以A端是类型,即X是A的实例(换句话说,A是X的类型),通过命令X.__class__我们可查看X的类型。再看,一条带箭头的实线从A端射向B端,B端是箭头端,实线代表父子关系,所以B端是父类,即A是B的子类这时候,我们通过将X端射向A端的虚线,向上抬,射向B端(你应该可以看到上图右上方有一条标志为implied[这个单词意思是隐藏]的向上虚线),就实现了表述X也是是B的实例的目的。也名副其实,虚线向上嘛。虚线向下规则也可以这样推出来,我就不演示了。

总的来说,面向对象体系里,有两种关系,一种是父子关系,通过父类与子类来描述,另一种是类型实例关系,通过类和实例来描述。而两条规则,是将类之间,类与实例之间的关系联系在一起。

到这里,可以进入主题了。


基本概念

对象内部:The Object Within

上面我们说了面向对象,那么对象(object)是什么呢?对象是python的重要核心之一:它是某个实体的抽象描述。对象拥有下面的特征:

  1. 对象标识(Identity):同一个(父)类实例化出来的对象,往往具有许多相同的特征,但是这些具有许多相同特征的对象肯定都有一个唯一的对象标识,当然,不同父类实例化出来的对象也是用对象标识作为判断对象的条件之一的;
  2. 值(A value):这意味着对象包含一堆属性。我们可以通过objectname.attributename的方式操作属性;
  3. 类型(A type):每个对象都有一个确切地类型。例如,对象“2”的类型是int;
  4. 一个或多个“Bases”(One or more bases):不是所有对象都有Bases,但一些特殊的对象会有,比如:。Bases类似于面向对象语言中的“基类”,“超类”。

如果你想知道一个对象在内存中的位置,你可以调用id(对象)来查看。在这里,我再次强调,在python中,一切都有对象的概念。数字2是对象,类型int也是对象...
typeBases(如果它们存在)非常重要,因为它们定义了一个对象和另一个对象之间的关系。请记住,typeBases本身也是对象,稍后会提到。
你也许会认为,对象有名字,但名字并不是对象的组成部分。对象的名字存在于这个对象的命名空间(namespace)之外或者是另一个对象的属性。也就是说:名字和这个对象不是存储在同一个“地方”

例子:测试一个整数对象

>>> two = 2  #==>(1)
>>> type(two)  #==>(2)
<class 'int'>
>>> type(type(two))  #==>(3)
<class 'type'>
>>> type(two).__bases__  #==>(4)
(<class 'object'>,)
>>> dir(two)  #==>(5)
['__abs__', '__add__', '__and__', '__bool__', '__ceil__', '__class__', '__delattr__', '__dir__', '__divmod__', '__doc__', '__eq__', '__float__', '__floor__', '__floordiv__', '__format__', '__ge__', '__getattribute__', '__getnewargs__', '__gt__', '__hash__', '__index__', '__init__', '__init_subclass__', '__int__', '__invert__', '__le__', '__lshift__', '__lt__', '__mod__', '__mul__', '__ne__', '__neg__', '__new__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__round__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__', 'bit_length', 'conjugate', 'denominator', 'from_bytes', 'imag', 'numerator', 'real', 'to_bytes']

(1):我们在当前命名空间给数字2分配一个名字。并将2和“two”绑定在起。
(2):这个对象的类型是<class 'int'>。你会在其它地方见到类似<type 'int'>int这样的输出,其实它们都是一个意思。
(3):额,<class 'int'>的类型是<class 'type'>.
(4):输出“类int”的基类。
(5):列出整型这个对象所有的属性。

可能会觉得有点乱,我稍微总结一下:数字2是类型int(一般来讲,在python中“类”和“类型”是同一种东西)的一个实例。倒过来说,int是数字2的类型。元组(<class 'object'>,)是类型int的超类(或说父类)。一个类型的超类可能不止一个,所以用元组表示。
现在,我们引出第一条规则:

一切皆为对象
上面说的数字2,类型int,int的超类<class 'object'>都是对象。除此之外,你定义的函数,方法...都是对象。


一块干净的画板

现在我们来建立python的对象系统。从一块干净的画板开始...,画板分为三部分,从左到右,分别代表类的类,类,类的实例。

我们会在这个画板中开启我们的学习之旅...


关系(Relationships)

我们谈及对象时,用两种关系来连接各种对象,使得对象之间产生联系:

  1. 父子关系( the subclass-superclass relationship);
  2. 类型实例关系( the type-instance relationship )。

在文章开头已经详细讨论过这两种关系了。


进入对象( Bring In The Objects)

第一个对象

我们测试两个对象:objecttype:
例子1:

>>> object   #===>(1)
<class 'object'>
>>> type     #===>(2)
<class 'type'>
>>> type(object)     #===>(3)
<class 'type'>
>>> object.__class__     #===>(4)
<class 'type'>
>>> object.__bases__     #===>(5)
()
>>> type.__class__     #===>(6)
<class 'type'>
>>> type.__bases__     #===>(7)
(<class 'object'>,)

(1),(2):python中的两个源对象的名字。我们先前说过type()是用来获对象的类型的。事实上,它既是一个对象,也是获取其它对象的类型的方法
(3),(4):查看object的类型。看到object是type的实例,我们另外也用.__class__来核实它和type()的输出是一样的。
(5):object没有超类,因为它本身就是所有对象的超类。
(6),(7):分别输出type的类型和超类。即,object是type的超类。type的类型是它自己

我们把例子1获取的信息描述在画板上:

object和type是python中的两个源对象,当我们尝试介绍它们是就会陷入“先有鸡还是现有蛋”难题,到底先介绍谁?事实上,它们是互相依赖对方来定义,所以它们不能分开而论。

继续我们的python实验:

>>> isinstance(object,object)    #===>(1)
True
>>> isinstance(type, object)     #===>(2)
True

(1):发生了什么?其实这里利用了虚线向上规则,type是object的子类,type的实例自然也是object的实例。object是type的实例啊。
(2):这里我参考的英文文档解释是:同时应用虚线向上和虚线向下规则。但我看得一脸懵逼。因为我觉的这里和(1)一样啊:type是object的子类,type的实例自然也是object的实例。type也是type的实例啊。

如果你认为上面的解释很混乱,不用理会它。不影响你理解这篇文章的主要目的。

新概念: type objects

typeobject都属于type objects。type objects翻译过来就是类型对象了。类型对象的特征:

  1. 它们用于表示程序中的抽象数据类型。例如,我们定义的一个类User会代表系统中所有的用户。int会代表系统中所有整形数字。
  2. 它们能被继承。这意味着你可以利用存在的类型对象创造出新的类型对象。已经存在的类型对象是新的类型对象的超类。
  3. 它们能被实例化。这意味着你可以利用已经存在的类型对象创造出新的实例对象。前者是后者的type
  4. 类型对象的类型是type
  5. 它们有时会被成为类型有时会被称为

你没有看错。在新版本的python中类型已经是同一样东西了。由一个很明显的地方就可以看出来。__class__type()的输出是一样的。

在旧版本的python中,是特指用class语句创造出来的东西。而内置类型例如int一般不会被认为是,而是被认为是类型。但在新版本中它们是同一样东西了。我觉得有必要为这个改变定义一条规则:
类是类型,类型也是类(Class is Type is Class)

在>=2.3版本的python中,类和类型是同一样东西。
The term type is equivalent to the term class in all version of Python >= 2.3.

类型和非类型(或者说类和非类)都是对象,但只有类型能够被继承。非类型拥有具体的值,所以被继承是毫无意义的,而且它也不能被继承。做简单的例子,就是类型int和它的实例2。int是类型,2是非类型。你说说,继承2有什么意义?

是否还是会疑惑到底社么是类型?什么是非类型?
这里有一条判断规则送给你:

如果一个对象,它的类型是“<class 'type'>”,那么,它是类型,否则不是。

还记得怎么判断一个对象的类型吗?没错的,__class__和type()随意你用。

小总结:

  • <class 'object'>的类型是<class 'type'>;
  • <class 'object'>的父类为空;
  • <class 'type'> 的类型是它自己本身;
  • <class 'type'> 是<class 'object'>的子类;
  • 在python中只要两种对象:类型和非类型。非类型也被称为实例。这里有英文原句,我不知怎么翻译了,很容易看懂,但不知如何说:There are only two kinds of objects in Python: to be unambiguous let's call these types and non-types. Non-types could be called instances, but that term could also refer to a type, since a type is always an instance of another type. Types could also be called classes, and I do call them classes from time to time.

注意我们在画板中只画出两个对象的直接关系,隐藏的关系就不画了,节省我们的精力和画板尺寸


更多内置对象

python这条船上可不止只有两个源对象。通过这两个源对象可以繁育出一堆对象:
Figure 2.2. 一些内置对象

上图中的一些内置类型,下面通过例子来测试:

>>> list    #====>(1)
<class 'list'>
>>> list.__class__    #====>(2)
<class 'type'>
>>> list.__bases__    #====>(3)
(<class 'object'>,)
>>> tuple.__class__,tuple.__bases__    #====>(4)
(<class 'type'>, (<class 'object'>,))
>>> dict.__class__,dict.__bases__    #和(4)一样原理
(<class 'type'>, (<class 'object'>,))
>>> mylist = [1,2,3]    #====>(5)
>>> mylist.__class__    #====>(6)
<class 'list'>
>>> mylist.__bases__    #====>(7)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'list' object has no attribute '__bases__'

(1):内置对象list;
(2):list的类型是<class 'type'>;
(3):list的超类是(<class 'object'>,);
(4):内置对象tuple.tuple的类型和超类分别是:<class 'type'>, (<class 'object'>,);
(5)list的一个实例mylist;
(6)实例mylist的类型是<class 'list'>;
(7)实例没有超类。

我们可以创造一个tuple或dict的实例,但我们不能创造一个mylist的实例。因为mylist不是一个类型,它仅仅是一个实例。

通过继承产生新对象

内置类型是python本身就有的。那么我们如何创造一个新的类型呢?
新的类型不能够凭空产生,它必须依赖已经存在的类型,于是,继承就呼之欲出了。

例子:通过继承产生新对象

# 在 Python 2.x,你得显式写出自定义的类继承于object:
class C(object):    #====>(1)
    pass

# In Python 3.x,不用显式写出object,如果你不写,则自动继承于object:
class C:    #====>(2)
    pass

class D(object):
    pass

class E(C, D):    #====>(3)
    pass

class MyList(list):    #====>(4)
    pass 

(1):class语句告诉python解释器要通过一个存在的类型创造一个新的类型;
(2):在python3.x可以省略掉(object)。
(3):多重继承;
(4):大多数内置类型可以被继承,但不是所有的都可以。

通过实例化产生新对象

Example 2.5.

obj = object()    #====>(1)

cobj = C()   #====>(2)

mylist = [1,2,3]    #====>(3)

(1),(2):利用类型名()的方式创造一个类型的实例。()中可能带参数;
(3):这是python利用内置类型创造实例的语法。没什么好说的。

注意:仅仅通过对<class 'object'>进行子类化,类型C就自动成为<class 'type'>的实例。原因在常见疑问的第二个问题中。

在以上的操作后,原本空白的画板可以画满了:


常见疑问

到这里你头脑中可能会有很多疑惑,下面列出其中一些问题以及答案,请酌情欣赏。有没有提到的请留言,我会努力搜索答案来解答:
Q: Python如何真正创建一个新对象?
A: 在python中,创造的新对象有两种:类型和非类型。类型可被继承和实例化。非类型本事就是一个实例。当python创造新对象时,它会用自己本身的类型作为新对象的类型。一般会用到两个方法__new__()__init__()。所以。每个对象都有类型。
Q:实例化的时候要指定类型,但是当继承时python如何知道用哪个类型?
它查看你继承的超类,并且使用超类的类型来作为新对象的类型。
在大多数的情况下,<class 'object'>的子类(和<class 'object'>的子类的子类等等)的类型都是<class 'type'>

>>> class A(object):
...     pass
...
>>> class B(A):
...     pass
...
>>> class C(B):
...     pass
...
>>> A.__class__, B.__class__, C.__class__
(<class 'type'>, <class 'type'>, <class 'type'>)

Q:我能够创造一个新的类型?
A:能,这就得元类出场了,通过属性__metaclass__你可以重新创造一个类型出来。这里我简单列一个例子。元类的话下面会简单介绍。

>>> class A(type):
...     pass
...
>>> class B(object, metaclass=A):
...     pass
...
>>> class C(B):
...     pass
...
>>> A.__class__, B.__class__, C.__class__
(<class 'type'>, <class '__main__.A'>, <class '__main__.A'>)

通过继承type,我们创造出新的类型<class '__main__.A'>

Q:wow!那我可以使用任何的类型作为metaclass的参数吗?
A:不能。只有继承了type的类能够做为metaclass的参数。

Q:我应该使用metaclass吗?
不建议使用。高手除外。


准备结束

一幅描绘python对象的图

我们最后得到一幅由不同对象组成的地图:

在大多数情况之下,我们都是学习第二列和第三列的内容。至于第一列,那是元类的领域了。不是所有人都要深入学习。

来解释一下上图的东西:

  1. 虚线可以从一列穿过另一列,例如从实例所在列穿到类所在列。(<type 'type'>例外);
  2. 实线不可以穿过其他列。再一次地,<type 'type'> -> <type 'object'> 是例外。
  3. 第三列不允许出现实线。因为实线代表继承。第三列地实例无法子类化;
  4. 第三列地对象也不允许被实例化;
  5. 第一,二列包含类型,第三列包含非类型;
  6. 如果创造一个继承<class 'type'>的对象,那么它会被放在第一列,即元类。这里继续强调,类和类型是一样的。<class 'type'><type 'type'>也是一样的。

注意:<class 'type'>是所有类型的类型。<class 'object'>也是所有对象的超类(除了它自己)


总结

这些内容是对前面的总结:

  1. 在python中有两种对象:

    • 类型对象:可以被实例化和继承;
    • 非类型对象:不可以被实例和继承。
  2. <class 'type'>和<class 'object'>是python中的两个源对象。

  3. 每个对象都有类型。用objectname.__class__查看。

  4. 每个类型对象都有超类(object除外),用objectname.__bases__可以查看。

  5. 通过继承产生的新对象都是类型对象。继承是用class语句来实现的。

  6. 通过实例化产生的新对象可能是类型对象,也可能是非类型对象。你看下图,虚线就表示实例化,第一列和第二列实例化产生的新对象就是类型对象。第三列实例化产生的新对象就是非类型对象。实例化是通过调用操作符()来实现的。比如你自定义了一个类myclass,实例化就是在myclass后增加()操作符完成的。也就是instance_of_myclass=myclass()

  7. 一些python的非类型对象可以通过特殊的语法来创造。例如[1, 2, 3]是list的实例。

  8. 在内部,python总是使用类型对象来创造新对象。新创造的对象是该类型对象的实例。(在这里,实例有两种意思:一通过继承产生的子类,二是通过实例化产生的具体实例。但平时我们说的实例就是只第二种)。python通过class语句中指定的超类的类型来决定新对象的类型

  9. issubclass(A,B)返回true当且仅当:

    • B在A.__bases__输出的元组之中;
    • 如果A在Z.__bases__输出的元组中,issubclass(Z,B)返回true.
  10. isinstance(A,B)返回true当且仅当:

    • A.__class__是B,或者
    • issubclass(A.class,B)返回true.

完结

这篇文章很长。因为水平限制,可能会出现错误。请批判性阅读。

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

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

相关文章

npm安装慢 ,卡在sill idealTree buildDeps不动

先说结论&#xff1a;node的默认镜像是国外的&#xff0c;修改镜像为国内地址。 报错截图&#xff1a; Failed to check for updates&#xff0c;开始以为是版本问题&#xff0c;并没有理会&#xff0c;直接创建项目&#xff0c;结果卡在了sill idealTree buildDeps&#xff08…

有关于torch.autograd.grad

torch.autograd模块给用户提供了一个自定义求导的接口。torch.autograd.grad可以手动地将loss对某部分参数进行梯度求导&#xff0c;特别适用于debug和观测。 笔者经常使用这个接口用于观测模型优化出现问题时&#xff0c;梯度值是否出现异常&#xff1b;以及用于代替tensorbo…

检验基础的 JavaScript 面试题

1. 下面代码的输出是什么&#xff1f; function sayHi() {console.log(name);console.log(age);var name "Lydia";let age 21; }sayHi(); A: Lydia 和 undefined B: Lydia 和 ReferenceError C: ReferenceError 和 21 D: undefined 和 ReferenceError 答案: D…

12月编程语言排行榜公布!一起来看变化!

2022年迎来了最后一个月&#xff0c;我们可以看到&#xff0c;在这一年中编程语言起起伏伏&#xff0c;有的语言始终炙手可热&#xff0c;而有的语言却逐渐“没落”… 日前&#xff0c;全球知名TIOBE编程语言社区发布了12月编程语言排行榜&#xff0c;有哪些新变化&#xff1f…

一篇博客搞定深度学习基本概念与反向传播

目录 深度学习的发展过程 深度学习的步骤 定义Neural NetWork 全前向连接 softmax介绍 定义loss函数 定义优化器选择最优参数optimization 反向传播Backpropagation 深度学习介绍 反向传播视频 深度学习的发展过程 perceptron(liner model)感知机——线性模型 perc…

ESP32入门基础之资源管理

文章目录1 ESP32-DevKitC V4&#xff08;ESP32-WROVER-E&IE&#xff09;板载资源2 FreeRTOS任务内存使用监控1 ESP32-DevKitC V4&#xff08;ESP32-WROVER-E&IE&#xff09;板载资源 ESP32-DevKitC V4 入门指南 esp32-devkitc开发板参数对比 在工程中使用函数查询可用…

HTML学生个人网站作业设计:基于HTML+CSS+JavaScript设计多用途的图文展示博客HTML模板(16页)

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

IPv4/IPv6协议分析 实验报告

实验名称&#xff1a; IPv4/IPv6协议分析实验 一、实验预习 1、实验目的 利用抓包工具&#xff08;Wireshark/Windump/Sniffer&#xff09;抓取IPv4/IPv6分组&#xff0c;以进一步熟悉和理解IPv4/IPv6格式规范与IP协议的工作原理 2、实验内容…

HBase Windows 安装

一、写在前面 在安装HBase之前&#xff0c;我们需要先安装JDK和Hadoop&#xff0c;具体JDK和Hadoop的安装我前面已经做过了&#xff0c;需要的话&#xff0c;请看我的另一篇博客&#xff1a;Hadoop Windows 安装 还是那句话&#xff0c;在安装HBase之前&#xff0c;我们需要搞清…

IDEA 一些实用性的设置(Doing)

文章目录设置鼠标滑轮修改字体大小设置自动导包和删包功能设置显示代码行号和方法间的间隔符设置忽略大小写提示设置文件多行显示tabs设置默认字体、字体大小和行间距设置鼠标滑轮修改字体大小 file——setting&#xff08;快捷键&#xff1a;CtrlAltS&#xff09;——editor—…

ELK(搜索与分析技术栈)

一、介绍 ELK其实并不是一款软件&#xff0c;而是一整套解决方案&#xff0c;是三个软件产品的首字母缩写&#xff0c;Elasticsearch&#xff0c;Logstash 和 Kibana。这三款软件都是开源软件&#xff0c;通常是配合使用&#xff0c;而且又先后归于 Elastic.co 公司名下&#…

HTML学生个人网站作业设计成品 HTML+CSS肖战明星人物介绍网页 web结课作业的源码

&#x1f389;精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业…

并发与竞争(三)自旋锁

文章目录自旋锁的概念什么是自旋锁&#xff1f;自旋锁的API函数&#xff08;一&#xff09;自旋锁的使用步骤其他自旋锁API函数&#xff08;二&#xff09;自旋锁的注意事项内核中自旋锁的实例自旋锁死锁写代码临界区在哪&#xff1f;最简单的实现逻辑完整实现自旋锁的概念 什…

Python pip更新教程(两种方式)

1. 直接采用命令行模式更新 1.1 搜索框搜索cmd&#xff0c;然后以管理员模式打开 1.2 执行命令 python -m pip install --upgrade pip1.3 查看更新后的版本 pip --version注&#xff1a;如果更新失败&#xff0c;可能是因为网络的问题&#xff0c;则选择第二种更新方法。 2.…

零基础怎么入门python

本文由正厚软件陈老师提供 “编程零基础&#xff0c;可以学习Python吗&#xff1f;” 这是很多初学者经常问的一个问题&#xff0c;我的回答是可以&#xff01;现在很多小学、初中也开始学习编程语言&#xff0c;选择的入门语言就是python。 python其实和学中文没什么区别&…

Windows 10关闭快速启动的方法

在Windows 8及其更高版本的Windows系统中&#xff0c;快速启动功能会被默认开启&#xff0c;开机时间也能大大缩短。但是在某些情况下&#xff0c;快速启动功能的开启会带来部分系统问题&#xff0c;从而无法正常使用电脑。那么我们该如何关闭快速启动呢&#xff1f; 快速启动的…

Redis06:Redis进阶部分

Redis进阶部分Redis配置文件详解Redis持久化持久化之RDB操作rdb优缺点Redis配置文件详解 Redis持久化 Redis是内存数据库&#xff0c;如果不将内存中的数据状态保存到磁盘&#xff0c;那么一旦服务器进程退出&#xff0c;服务器中的数据库状态也会消失&#xff0c;所以Redis提供…

taro3.3.12升级至3.5.8解决支付宝小程序启动基础库2.0构建报错---slot 的祖先节点中未找到 element

项目&#xff1a;taro3 vue3 taro版本&#xff1a;3.3.12 支付宝在上传版本时要求用基础库2.0编译&#xff0c;否则报错&#xff0c;启动2.0编译后&#xff0c; 会有如下错误&#xff1a; 解决方案&#xff1a;社区里面说是要升级taro >3.4.0 步骤1、查看taro版本 – …

bmp位图格式详细介绍-1/4/8/16/24/32bit、存储格式等

目录 一、概述 二、.bmp格式文件详解  2.1 位图文件头  2.2 位图信息头  2.3 调色板  2.4 位图数据 三、位图的其他知识  3.1 压缩的位图 一、概述 bmp是英文Bitmap&#xff08;位图&#xff09;的简写&#xff0c;它是Windows操作系统中的标准图像文件格式&#xff0c;随…

FFplay音频滤镜分析

音频流的 滤镜是通过 configure_audio_filters() 函数来创建的&#xff0c;因为 ffplay 为了代码的通用性&#xff0c;即便命令行参数不使用滤镜&#xff0c;AVFrame 也会过一遍 空滤镜做下样子。 configure_audio_filters() 函数的流程图如下&#xff1a; configure_audio_fi…