面向对象初级

一. 面向对象

面向对象编程(Object-oriented Programming,简称 OOP),是一种封装代码的方法。其实,在前面章节的学习中,我们已经接触了封装,比如说,将乱七八糟的数据扔进列表中,这就是一种简单的封装,是数据层面的封装;把常用的代码块打包成一个函数,这也是一种封装,是语句层面的封装。

代码封装,其实就是隐藏实现功能的具体代码,仅留给用户使用的接口,就好像使用计算机,用户只需要使用键盘、鼠标就可以实现一些功能,而根本不需要知道其内部是如何工作的。

本节所讲的面向对象编程,也是一种封装的思想,不过显然比以上两种封装更先进,它可以更好地模拟真实世界里的事物(将其视为对象),并把描述特征的数据和代码块(函数)封装到一起。

打个比方,若在某游戏中设计一个乌龟的角色,应该如何来实现呢?使用面向对象的思想会更简单,可以分为如下两个方面进行描述:

  1. 从表面特征来描述,例如,绿色的、有 4 条腿、重 10 kg、有外壳等等。
  2. 从所具有的的行为来描述,例如,它会爬、会吃东西、会睡觉、会将头和四肢缩到壳里,等等。

如果将乌龟用代码来表示,则其表面特征可以用变量来表示,其行为特征可以通过建立各种函数来表示。参考代码如下所示:

class tortoise:bodyColor = "绿色"footNum = 4weight = 10hasShell = True#会爬def crawl(self):print("乌龟会爬")#会吃东西def eat(self):print("乌龟吃东西")#会睡觉def sleep(self):print("乌龟在睡觉")#会缩到壳里def protect(self):print("乌龟缩进了壳里")

注意,以上代码仅是为了演示面向对象的编程思想,具体细节后续会做详细介绍。

因此,从某种程序上,相比较只用变量或只用函数,使用面向对象的思想可以更好地模拟现实生活中的事物。

不仅如此,在 Python 中,所有的变量其实也都是对象,包括整形(int)、浮点型(float)、字符串(str)、列表(list)、元组(tuple)、字典(dict)和集合(set)。以字典(dict)为例,它包含多个函数供我们使用,例如使用 keys() 获取字典中所有的键,使用 values() 获取字典中所有的值,使用 item() 获取字典中所有的键值对,等等。

面向对象中,常用术语包括:

  • :可以理解是一个模板,通过它可以创建出无数个具体实例。比如,前面编写的 tortoise 表示的只是乌龟这个物种,通过它可以创建出无数个实例来代表各种不同特征的乌龟(这一过程又称为类的实例化)。
  • 对象:类并不能直接使用,通过类创建出的实例(又称对象)才能使用。这有点像汽车图纸和汽车的关系,图纸本身(类)并不能为人们使用,通过图纸创建出的一辆辆车(对象)才能使用
  • 属性:类中的所有变量称为属性。例如,tortoise 这个类中,bodyColor、footNum、weight、hasShell 都是这个类拥有的属性。
  • 方法:类中的所有函数通常称为方法。不过,和函数所有不同的是,类方法至少要包含一个 self 参数(后续会做详细介绍)。例如,tortoise 类中,crawl()、eat()、sleep()、protect() 都是这个类所拥有的方法,类方法无法单独使用,只能和类的对象一起使用。

二. 类的定义和使用

2.1 类的定义

Python 程序中类的使用顺序是这样的:

  1. 创建(定义)类,也就是制作图纸的过程;
  2. 创建类的实例对象(根据图纸造出实际的物品),通过实例对象实现特定的功能。

定义一个类使用 class 关键字实现,其基本语法格式如下:

class 类名:多个(≥0)类属性...多个(≥0)类方法...

注意,无论是类属性还是类方法,对于类来说,它们都不是必需的,可以有也可以没有。另外,Python 类中属性和方法所在的位置是任意的,即它们之间并没有固定的前后次序。

和变量名一样,类名本质上就是一个标识符,因此我们在给类起名字时,必须让其符合 Python 的语法。有读者可能会问,用 a、b、c 作为类的类名可以吗?从 Python 语法上讲,是完全没有问题的,但作为一名合格的程序员,我们必须还要考虑程序的可读性。

注意,如果由单词构成类名,建议每个单词的首字母大写,其它字母小写。

给类起好名字之后,其后要跟有冒号(:),表示告诉 Python 解释器,下面要开始设计类的内部功能了,也就是编写类属性和类方法。

其实,类属性指的就是包含在类中的变量;而类方法指的是包含类中的函数。换句话说,类属性和类方法其实分别是包含类中的变量和函数的别称。需要注意的一点是,同属一个类的所有类属性和类方法,要保持统一的缩进格式,通常统一缩进 4 个空格。

Python 变量和函数的使用,前面章节中已经做了详细的介绍,这里不再重复赘述。

通过上面的分析,可以得出这样一个结论,即 Python 类是由类头(class 类名)和类体(统一缩进的变量和函数)构成。例如,下面程序定义一个 TheFirstDemo 类:

class TheFirstDemo:# 下面定义了一个类属性add = 'https://www.baidu.com/'# 下面定义了一个say方法def say(self, content):print(content)

和函数一样,我们也可以为类定义说明文档,其要放到类头之后,类体之前的位置,如上面程序中第二行的字符串,就是 TheFirstDemo 这个类的说明文档。

另外分析上面的代码可以看到,我们创建了一个名为 TheFirstDemo 的类,其包含了一个名为 add 的类属性。注意,根据定义属性位置的不同,在各个类方法之外定义的变量称为类属性或类变量(如 add 属性),而在类方法中定义的属性称为实例属性(或实例变量)。

同时,TheFirstDemo 类中还包含一个 say() 类方法,细心的读者可能已经看到,该方法包含两个参数,分别是 self 和 content。可以肯定的是,content 参数就只是一个普通参数,没有特殊含义,但 self 比较特殊,并不是普通的参数,它的作用会在后续中详细介绍

事实上,我们完全可以创建一个没有任何类属性和类方法的类,换句话说,Python 允许创建空类,例如:

class Empty:pass

可以看到,如果一个类没有任何类属性和类方法,那么可以直接用 pass 关键字作为类体即可。但在实际应用中,很少会创建空类,因为空类没有任何实际意义。

2.2 init()类构造方法

在创建类时,我们可以手动添加一个 init() 方法,该方法是一个特殊的类实例方法,称为构造方法(或构造函数)。构造方法用于创建对象时使用,每当创建一个类的实例对象时,Python 解释器都会自动调用它。Python 类中,手动添加构造方法的语法格式如下:

def __init__(self,...):代码块

注意,此方法的方法名中,开头和结尾各有 2 个下划线,且中间不能有空格。Python 中很多这种以双下划线开头、双下划线结尾的方法,都具有特殊的意义。

另外,init() 方法可以包含多个参数,但必须包含一个名为 self 的参数,且必须作为第一个参数。也就是说,类的构造方法最少也要有一个 self 参数。例如,仍以 TheFirstDemo 类为例,添加构造方法的代码如下所示:

class TheFirstDemo:#构造方法def __init__(self):print("调用构造方法")# 下面定义了一个类属性add = 'http://www.baidu.com'# 下面定义了一个say方法def say(self, content):print(content)

注意,即便不手动为类添加任何构造方法,Python 也会自动为类添加一个仅包含 self 参数的构造方法。

仅包含 self 参数的 __init__() 构造方法,又称为类的默认构造方法。

在上面代码的后面,顶头(不缩进)直接添加如下代码:

zhangsan = TheFirstDemo()

这行代码的含义是创建一个名为 zhangsan 的 TheFirstDemo 类对象。运行代码可看到如下结果:

调用构造方法

显然,在创建 zhangsan 这个对象时,隐式调用了我们手动创建的 init() 构造方法。

不仅如此,在 init() 构造方法中,除了 self 参数外,还可以自定义一些参数,参数之间使用逗号“,”进行分割。例如,下面的代码在创建 init() 方法时,额外指定了 2 个参数:

class CLanguage:def __init__(self,name,add):print(name,"的网址为:",add)
#创建 add 对象,并传递参数给构造函数
add = CLanguage("百度","http://www.baidu.com")

注意,由于创建对象时会调用类的构造方法,如果构造函数有多个参数时,需要手动传递参数,传递方式如代码中所示(后续章节会做详细讲解)。

运行以上代码,执行结果为:

百度 的网址为: http://www.baidu.com

可以看到,虽然构造方法中有 self、name、add 3 个参数,但实际需要传参的仅有 name 和 add,也就是说,self 不需要手动传递参数。

2.3 类的实例化

对已定义好的类进行实例化,其语法格式如下:

类名(参数)

定义类时,如果没有手动添加 init() 构造方法,又或者添加的 init() 中仅有一个 self 参数,则创建类对象时的参数可以省略不写。

例如,如下代码创建了名为 CLanguage 的类,并对其进行了实例化:

class CLanguage :# 下面定义了2个类变量name = "百度"add = "http://baidu.com"def __init__(self,name,add):#下面定义 2 个实例变量self.name = nameself.add = addprint(name,"网址为:",add)# 下面定义了一个say实例方法def say(self, content):print(content)
# 将该CLanguage对象赋给clanguage变量
clanguage = CLanguage("百度","http://www.baidu.com")

在上面的程序中,由于构造方法除 self 参数外,还包含 2 个参数,且这 2 个参数没有设置默认参数,因此在实例化类对象时,需要传入相应的 name 值和 add 值(self 参数是特殊参数,不需要手动传值,Python 会自动传给它值)。

2.4 类对象的使用

定义的类只有进行实例化,也就是使用该类创建对象之后,才能得到利用。总的来说,实例化后的类对象可以执行以下操作:

  • 访问或修改类对象具有的实例变量,甚至可以添加新的实例变量或者删除已有的实例变量;
  • 调用类对象的方法,包括调用现有的方法,以及给类对象动态添加方法。
2.4.1 类对象访问变量或方法

使用已创建好的类对象访问类中实例变量的语法格式如下:

类对象名.变量名

使用类对象调用类中方法的语法格式如下:

对象名.方法名(参数)

注意,对象名和变量名以及方法名之间用点 “.” 连接。

例如,下面代码演示了如何通过 clanguage 对象调用类中的实例变量和方法:

class CLanguage :# 下面定义了2个类变量name = "百度"add = "http://baidu.com"def __init__(self,name,add):#下面定义 2 个实例变量self.name = nameself.add = addprint(name,"网址为:",add)# 下面定义了一个say实例方法def say(self, content):print(content)
# 将该CLanguage对象赋给clanguage变量
clanguage = CLanguage("百度","http://www.baidu.com")#输出name和add实例变量的值
print(clanguage.name,clanguage.add)
#修改实例变量的值
clanguage.name="Python教程"
clanguage.add="http://c.biancheng.net/python"
#调用clanguage的say()方法
clanguage.say("人生苦短,我用Python")
#再次输出name和add的值
print(clanguage.name,clanguage.add)

运行结果为:

百度 网址为: http://www.baidu.com
百度 http://www.baidu.com
人生苦短,我用Python
Python教程 http://c.biancheng.net/python
2.4.2 给类对象动态添加/删除变量

Python 支持为已创建好的对象动态增加实例变量,方法也很简单,举个例子:

# 为clanguage对象增加一个money实例变量
CLanguage.money= 159.9
print(CLanguage.money)

运行结果为:

159.9

可以看到,通过直接增加一个新的实例变量并为其赋值,就成功地为 CLanguage 对象添加了 money 变量。

既然能动态添加,那么是否能动态删除呢?答案是肯定的,使用 del 语句即可实现,例如:

#删除新添加的 money 实例变量
del CLanguage.money
#再次尝试输出 money,此时会报错
print(CLanguage.money)

运行程序会发现,结果显示 AttributeError 错误:

Traceback (most recent call last):File "C:\Users\admin\Desktop\new.py", line 21, in <module>print(CLanguage.money)
AttributeError: type object 'CLanguage' has no attribute 'money'
2.4.3 给类对象动态添加方法

Python 也允许为对象动态增加方法。以本节开头的 Clanguage 类为例,由于其内部只包含一个 say() 方法,因此该类实例化出的 Clanguage 对象也只包含一个 say() 方法。但其实,我们还可以为 Clanguage 对象动态添加其它方法。

需要注意的一点是,为 clanguage 对象动态增加的方法,Python 不会自动将调用者自动绑定到第一个参数(即使将第一个参数命名为 self 也没用)。例如如下代码

# 先定义一个函数
def info(self):print("---info函数---", self)
# 使用info对clanguage的foo方法赋值(动态绑定方法)
clanguage.foo = info
# Python不会自动将调用者绑定到第一个参数,
# 因此程序需要手动将调用者绑定为第一个参数
clanguage.foo(clanguage)  # ①# 使用lambda表达式为clanguage对象的bar方法赋值(动态绑定方法)
clanguage.bar = lambda self: print('--lambda表达式--', self)
clanguage.bar(clanguage) # ②

上面的第 5 行和第 11 行代码分别使用函数、lambda 表达式为 clanguage 对象动态增加了方法,但对于动态增加的方法,Python 不会自动将方法调用者绑定到它们的第一个参数,因此程序必须手动为第一个参数传入参数值,如上面程序中 ① 号、② 号代码所示.

2.5 类的析构函数

class Person:def __init__(self,name,age,sex='男'):self.name = nameself.age =ageself.sex = sexdef play(self):print('%s 正在玩游戏---' % self.name)def search(self):print('%s 正在找资料---' % self.name)def __del__(self):print('%s 事情做完了---' % self.name)

交互模式下运行后:

>>> kk = Person('空空',21)
>>> kk.name
'空空'
>>> kk.play()
空空 正在玩游戏---
>>> kk.__del__()
空空 事情做完了---
>>> del kk
空空 事情做完了---
>>> kk
Traceback (most recent call last):File "<pyshell#5>", line 1, in <module>kk
NameError: name 'kk' is not defined
>>> kk.name
Traceback (most recent call last):File "<pyshell#6>", line 1, in <module>kk.name
NameError: name 'kk' is not defined

在类中增加__del__函数,当删除实例的时候,就会调用此方法
del关键字用来删除对象

三. 继承和重用

3.1 继承

灵魂三问

什么是继承?
继承是一种创建新的类的方式,新创建的叫子类,继承的叫父类、超类、基类。
特点:子类可以使用父类的属性(特征、技能)
继承是类与类之间的关系

为什么要继承?
减少代码冗余、提高重用性

如何用继承?
python中类的继承分为:单继承和多继承

单继承

class Person:def __init__(self,name,age,sex='男'):self.name = nameself.age =ageself.sex = sexdef play(self):print('%s 正在玩游戏---' % self.name)def search(self):print('%s 正在找资料---' % self.name)def __del__(self):print('%s 事情做完了---' % self.name)class GuangDong(Person):def play(self):print('广东人爱喝茶')class SiChuan(Person):def play(self):print('四川人爱打雀雀儿')

交互模式下运行后:

>>> stone = GuangDong('stone',18)
>>> dong = SiChuan('feng',18)
>>> stone.play()
广东人爱喝茶
>>> dong.play()
四川人爱打雀雀儿
>>> dong.search()
feng 正在找资料---

GuangDongSiChuan称为是Person子类,也可以成为派生类
Person称为是GuangDongSiChuan父类,也是object子类
object成为是所有类的父类

  • 子类获得了父类全部非私有的功能。
  • 子类不能继承父类中的私有方法,也不能被调用父类的私有方法。
  • 对于父类中扩展的非私有方法,子类可以拿来即用。

新式类、经典类

  • 继承了object的类以及该类的子类,都是新式类。在Python3中如果一个类没有继承任何类,则默认继承object类。因此python3中都是新式类
  • 没有继承object的类以及该类的子类,都是经典类。在Python2中如果一个类没有继承任何类,不会继承object类。因此,只有Python2中有经典类。

派生类
派生,就是在子类继承父类的属性的基础上,派生出自己的属性。子类有不同于父类的属性,这个子类叫做派生类。通常情况下,子类和派生类是同一个概念,因为子类都是有不同于父类的属性,如果子类和父类属性相同,就没必要创建子类了。

多继承:

class HunXue(GuangDong,SiChuan):def play(self):print('%s 即爱喝茶,又喜欢打麻将' % self.name)super().play()    #此处 super() 调用的是父级元素

交互模式下运行后:

>>> ks = HunXue('小明',18)
>>> ks.play()
小明 即爱喝茶,又喜欢打麻将
广东人爱喝茶

多继承时,只需要在继承时增加需要继承的类即可
虽然有继承SiChuan类,但是并没有调用SiChuan类的play方法,但为什么打印了它的方法?

多继承的继承顺序:

>>> HunXue.__base__
<class '__main__.GuangDong'>
>>> HunXue.__bases__
(<class '__main__.GuangDong'>, <class '__main__.SiChuan'>)
>>> HunXue.mro()
[<class '__main__.HunXue'>, <class '__main__.GuangDong'>, <class '__main__.SiChuan'>, <class '__main__.Person'>, <class 'object'>]

通过调用__base__和__bases__可以查看到,类继承的第一个和所有类
通过mro方法可以看到类的mro查找顺序
Python对于所有类会自动生成mro查找顺序,此顺序决定了向上查找方法的过程

3.2 重用

子类继承了父类,那么子类就拥有了父类所有的类属性和类方法。通常情况下,子类会在此基础上,扩展一些新的类属性和类方法。

但凡事都有例外,我们可能会遇到这样一种情况,即子类从父类继承得来的类方法中,大部分是适合子类使用的,但有个别的类方法,并不能直接照搬父类的,如果不对这部分类方法进行修改,子类对象无法使用。针对这种情况,我们就需要在子类中重复父类的方法。

举个例子,鸟通常是有翅膀的,也会飞,因此我们可以像如下这样定义个和鸟相关的类:

class Bird:#鸟有翅膀def isWing(self):print("鸟有翅膀")#鸟会飞def fly(self):print("鸟会飞")

但是,对于鸵鸟来说,它虽然也属于鸟类,也有翅膀,但是它只会奔跑,并不会飞。针对这种情况,可以这样定义鸵鸟类:

class Ostrich(Bird):# 重写Bird类的fly()方法def fly(self):print("鸵鸟不会飞")

可以看到,因为 Ostrich 继承自 Bird,因此 Ostrich 类拥有 Bird 类的 isWing() 和 fly() 方法。其中,isWing() 方法同样适合 Ostrich,但 fly() 明显不适合,因此我们在 Ostrich 类中对 fly() 方法进行重写。

重写,有时又称覆盖,是一个意思,指的是对类中已有方法的内部实现进行修改。

在上面 2 段代码的基础上,添加如下代码并运行:

class Bird:#鸟有翅膀def isWing(self):print("鸟有翅膀")#鸟会飞def fly(self):print("鸟会飞")
class Ostrich(Bird):# 重写Bird类的fly()方法def fly(self):print("鸵鸟不会飞")# 创建Ostrich对象
ostrich = Ostrich()
#调用 Ostrich 类中重写的 fly() 类方法
ostrich.fly()

运行结果为:

鸵鸟不会飞

显然,ostrich 调用的是重写之后的 fly() 类方法。

如何调用被重写的方法

事实上,如果我们在子类中重写了从父类继承来的类方法,那么当在类的外部通过子类对象调用该方法时,Python 总是会执行子类中重写的方法。

这就产生一个新的问题,即如果想调用父类中被重写的这个方法,该怎么办呢?

很简单,前面讲过,Python 中的类可以看做是一个独立空间,而类方法其实就是出于该空间中的一个函数。而如果想要全局空间中,调用类空间中的函数,只需要在调用该函数是备注类名即可。举个例子:

class Bird:#鸟有翅膀def isWing(self):print("鸟有翅膀")#鸟会飞def fly(self):print("鸟会飞")
class Ostrich(Bird):# 重写Bird类的fly()方法def fly(self):print("鸵鸟不会飞")# 创建Ostrich对象
ostrich = Ostrich()
#调用 Bird 类中的 fly() 方法
Bird.fly(ostrich)

运行结果为:

鸟会飞

此程序中,需要大家注意的一点是,使用类名调用其类方法,Python 不会为该方法的第一个 self 参数自定绑定值,因此采用这种调用方法,需要手动为 self 参数赋值。

通过类名调用实例方法的这种方式,又被称为未绑定方法。

四. 作业

本节作业:

1、定义一个账户类,可以创建账户、存款、取款 、查询余额、以及销户等操作
2、现在三个人分别去开户,存款 和 销户,请利用上面的类实现出来
提示:账户必备要素:1、账户名 2、密码 3、余额

上节答案:
1、利用datetime模块,批量生成6月份每天的txt文件
2、生成上面的文件之后,再一次在每个文件中写入文件名
3、将上面生成的所有文件名之后加上‘_NEW’

from datetime import *
import os
def zuoye():begin_date = date(2020,6,1)end_date = date(2020,6,30)while begin_date <= end_date:file_date = begin_date.strftime('%Y-%m-%d')with open('{}.txt'.format(file_date),'w+',encoding='utf-8') as f:f.write(file_date)begin_date += timedelta(days=1)for i in range(1,31):if i < 10:os.rename('2020-06-0{}.txt'.format(i),'2020-06-0{}_NEW.txt'.format(i))elif i >= 10:os.rename('2020-06-{}.txt'.format(i),'2020-06-{}_NEW.txt'.format(i))zuoye()  #执行该函数

运行结果截图如下:

4、假设有一个英文文本文件,编写一个程序读取其内容,并将里面的大写字母
变成小写字母,小写字母变成大写字母(字符串swapcase方法)

with open('html.txt','r+') as f:str_1 = f.read()str_2 = str_1.swapcase()f.seek(0)f.write(str_2)

运行结果截图如下:

Python全栈开发-Python基础教程-07 面向对象初级相关推荐

  1. Python全栈开发【基础-09】深浅拷贝+while循环

    专栏介绍: 本专栏为Python全栈开发系列文章,技术包括Python基础.函数.文件.面向对象.网络编程.并发编程.MySQL数据库.HTML.JavaScript.CSS.JQuery.boots ...

  2. Python全栈开发-Day1-Python基础1

    目录 Python介绍 Python 2 or 3? 安装 Hello World程序 变量 用户输入 模块初识 .pyc是个什么鬼? 数据类型初识 数据运算 表达式if ...else语句 表达式f ...

  3. Python全栈开发零基础学习通关秘籍:2018新手入门指南

    一.Python语言 1.1基础语法 1.1.1 python概述 1.1.2数据的存储 1.1.3软件安装 1.1.4第一个Python程序 1.1.5注释 1.1.6输出与输入 1.1.7标识符 ...

  4. Python全栈开发【基础二】

    本节内容: Python 运算符(算术运算.比较运算.赋值运算.逻辑运算.成员运算) 基本数据类型(数字.布尔值.字符串.列表.元组.字典) 其他(编码,range,for,while) Python ...

  5. Python全栈开发-Python爬虫-03 正则表达式详解

    正则表达式 一. 什么是正则表达式 正则表达式,又称规则表达式,通常被用来检索.替换那些符合某个模式(规则)的文本. 正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符.及这些特定 ...

  6. Python全栈开发-Python爬虫-05 爬取猫眼电影榜单信息

    爬取猫眼电影榜单信息(翻页) 一. 获取url及headers 首先进入猫眼电影首页: 猫眼电影 之后点击菜单栏的 榜单 并在下面选择 TOP100榜 接着右击检查并刷新界面,在Network中找到4 ...

  7. 【Python全栈开发从入门到实战】持续更新中......

    本专栏为Python全栈开发系列文章,技术包括Python基础.函数.文件.面向对象.网络编程.并发编程.MySQL数据库.HTML.JavaScript.CSS.JQuery.bootstrap.W ...

  8. flask python web优品课堂_Python Flask Web网站编程全栈开发系列高清视频教程-价值2499...

    0 s: n8 F- K0 _5 i( I Python Flask Web网站编程全栈开发系列高清视频教程& ?- Y2 }3 U1 k9 t/ k! i 这是2016年11月第二期,跟第三 ...

  9. python 全栈开发,Day32(知识回顾,网络编程基础)

    python 全栈开发,Day32(知识回顾,网络编程基础) 一.知识回顾 正则模块 正则表达式 元字符 :. 匹配除了回车以外的所有字符\w 数字字母下划线\d 数字\n \s \t 回车 空格 和 ...

最新文章

  1. 配置springmvc在其他类中(spring容器外)获取注入bean
  2. 帆软填报增加记录提交成功后没有_大病医疗填报图解
  3. 解题报告 - 牛客练习赛63 C - 牛牛的揠苗助长(货仓选址+二分)
  4. 【Netty】Netty 入门案例分析 ( Netty 模型解析 | Netty 服务器端代码 | Netty 客户端代码 )
  5. javascript select option对象总结
  6. axios post body参数_09-axios
  7. 计算机网络-基本概念(7)【网络层】-多协议标记交换MPLS
  8. android console命令,我们可以通过两种方式进入Android的console: 1. 直接执行命令emulator -shell; 2....
  9. 尾气冒黑烟是什么问题_烟囱里冒得白烟、黑烟、黄烟有什么危害?
  10. Notepad++没有插件管理器(Plugin Manager)的解决方法
  11. codeup21280:LIS最长不下降子序列问题(可不连续-dp基础题)
  12. ISO9000和CMM
  13. 操作系统期末复习【超实用】
  14. error: comparison between distinct pointer types ‘char*’ and ‘unsigned char*’ lacks a cast 解决方法
  15. Git Pull Failed:You have not concluded your merge.Exiting because of unfinished merge
  16. 赛效:Xmind思维导图怎么用 新手使用教程分享
  17. pythoncad标注教程_CAD 2014二维三维建模渲染标注基础与提升视频教程
  18. 汇编语言中间接寻址(间接操作数)与变址寻址(变址操作数)的区别
  19. CDH6.3.1监控界面Hive修改参数
  20. NPS:使用 Windows NPS Server 部署 802.1X 无线认证(1)

热门文章

  1. linux iperf测试带宽,使用iperf测试峰值带宽
  2. Android Studio —— ArrayAdapter
  3. 中国历朝地图[11P]
  4. 《C语言的自学教程 》,《自学C语言》初级教程 - 目录
  5. coursera python证书_IBM数据科学证书 | 你想要的一站式新手入门课!
  6. typeof的语法和使用
  7. SuperMap imobilelite for Android中通过iserver加载一幅地图
  8. ThreadLocal 与 static 变量
  9. ARP病毒攻击的防范和处理及方法
  10. kafka在windows下单机版搭建