@R星校长

Python 教程 day02

第七章 类和对象

面向对象编程介绍

  面向对象编程——Object Oriented Programming,简称 OOP,是一种程序设计思想。OOP 把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数。面向对象是一种对现实世界理解和抽象的方法。
  “面向过程” (Procedure Oriented) 是一种以过程为中心的编程思想。“面向过程”也可称之为“面向记录”编程思想,他们不支持丰富的“面向对象”特性(比如继承、多态、封装),并且它们不允许混合持久化状态和域逻辑。
  就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了。
  面向过程是一件事“该怎么做“,面向对象是一件事“该让谁来做”,然后那个“谁”就是对象,他要怎么做是他自己的事,反正最后一群对象合力能把事做好就行了。
  面向对象三个特性:继承,封装,多态。

类和对象

面向对象编程的 2 个非常重要的概念:类和对象
对象是面向对象编程的核心,在使用对象的过程中,为了将具有共同特征和行为的一组对象抽象定义,提出了另外一个新的概念——类
类就相当于制造飞机时的图纸,用它来进行创建的飞机就相当于对象


  1. 人以类聚 物以群分。 具有相似内部状态和运动规律的实体的集合(或统称为抽象)。 具有相同属性和行为事物的统称
    类是抽象的,在使用的时候通常会找到这个类的一个具体的存在,使用这个具体的存在。一个类可以找到多个对象

  2. 对象
    某一个具体事物的存在 ,在现实世界中可以是看得见摸得着的。 可以是直接使用的

  3. 类和对象之间的关系小总结:类就是创建对象的模板

  4. 练习:区分类和对象

     奔驰汽车 类 奔驰smart 类 张三的那辆奔驰smart 对象 狗 类 大黄狗 类 李四家那只大黄狗 对象 水果 类 苹果 类 红苹果 类 红富士苹果 类 我嘴里吃了一半的苹果 对象
    
  5. 类的构成

    类(Class) 由3个部分构成类的名称:类名类的属性:一组数据类的方法:允许对进行操作的方法 (行为)<1> 举例:1)人类设计,只关心3样东西:事物名称(类名):人(Person)属性:身高(height)、年龄(age)方法(行为/功能):跑(run)、打架(fight)2)狗类的设计类名:狗(Dog)属性:品种 、毛色、性别、名字、 腿儿的数量方法(行为/功能):叫 、跑、咬人、吃、摇尾巴
    

定义类与创建对象

1、类的定义
定义一个类,格式如下:
class 类名: 方法列表
demo:定义一个Car类

# 定义类
class Car:
# 方法
def getCarInfo(self): print('车轮子个数:%d, 颜色%s'%(self.wheelNum, self.color))
def move(self): print("车正在移动...")

说明:
1、定义类时有2种:新式类和经典类,上面的 Car 为经典类,如果是 Car(object) 则为新式类
2、类名的命名规则按照 “大驼峰”

2、创建对象
通过上一节课程,定义了一个 Car 类;就好比有车一个张图纸,那么接下来就应该把图纸交给生成工人们去生成了。
python 中,可以根据已经定义的类去创建出一个个对象
创建对象的格式为:
对象名 = 类名()
创建对象demo:

# 定义类
class Car:
# 移动
def move(self): print('车在奔跑...')
# 鸣笛
def toot(self):#self可以不写self,方法中必须有且一个参数。
#第一个参数表示当前对象。名字随便取,但是习惯都写self print("车在鸣笛...嘟嘟..")
# 创建一个对象,并用变量BMW来保存它的引用
BMW = Car()
BMW.color = '黑色'
BMW.wheelNum = 4#轮子数量
BMW.move()
BMW.toot()
print(BMW.color)
print(BMW.wheelNum)


总结:
1、BMW = Car(),这样就产生了一个Car的实例对象,一定在内存中有一块空间存放对象的数据信息。此时也可以通过实例对象 BMW 来访问属性或者方法
2、第一次使用 BMW.color = ‘黑色’ 表示给BMW这个对象添加属性,如果后面再次出现 BMW.color = xxx 表示对属性进行修改
3、BMW 是一个对象,它拥有属性(数据)和方法(函数)
4、当创建一个对象时,就是用一个模子,来制造一个实物

self

1、理解 self
看如下示例:

class Car:def move(self):print("汽车在飞驰。。。")def toot(self):print("汽车鸣笛:滴滴")def printInfo(self):print("轮子数:%d,颜色:%s"%(self.wheelNum,self.color))def myPrint(self):self.printInfo()
car = Car()
car.wheelNum = 4
car.color = "green"
# car.printInfo()
car.myPrint()

总结
1、所谓的self,可以理解为自己
2、可以把self当做C++中类里面的this指针一样理解,就是对象自身的意思
3、某个对象调用其方法时,python解释器会把这个对象作为第一个参数传递给self,所以开发者只需要传递后面的参数即可

2、__init__()方法

想一想:
在上一小节的demo中,我们已经给BMW这个对象添加了2个属性,wheelNum(车的轮胎数量)以及color(车的颜色),试想如果再次创建一个对象的话,肯定也需要进行添加属性,显然这样做很费事,那么有没有办法能够在创建对象的时候,就顺便把车这个对象的属性给设置呢?

<1>使用方式

def 类名:
#初始化方法,用来完成一些默认的设定def__init__():pass

<2> __init__()方法的调用

# 定义汽车类
Class Car:def __init__(self): self.wheelNum = 4 self.color = 'red'def move(self): print('车在跑,目标:夏威夷')
# 创建对象
BMW = Car()
print('车的颜色为:%s'%BMW.color)
print('车轮胎数量为:%d'%BMW.wheelNum)

总结1
当创建Car对象后,在没有调用__init__()方法的前提下,BMW就默认拥有了2个属性wheelNum和color,原因是__init__()方法是在创建对象后,就立刻被默认调用了
想一想:
既然在创建完对象后__init__()方法已经被默认的执行了,那么能否让对象在调用__init__()方法的时候传递一些参数呢?如果可以,那怎样传递呢?

# 定义汽车类
Class Car:def__init__(self, newWheelNum, newColor): self.wheelNum = newWheelNum self.color = newColor def move(self): print('车在跑,目标:夏威夷')
# 创建对象
BMW = Car(4, 'green')
print('车的颜色为:%s'%BMW.color)
print('车轮子数量为:%d'%BMW.wheelNum)

总结2
1、__init__()方法,在创建一个对象之后默认被调用,不需要手动调用
2、__init__(self)中,默认有1个参数名字为self,如果在创建对象时传递了2个实参,那么__init__(self)中出了self作为第一个形参外还需要2个形参,例如__init__(self,x,y)
3、__init__(self)中的self参数,不需要开发者传递,python解释器会自动把当前的对象引用传递进去

3、__new__方法

classA(object):def__init__(self): print("这是 init 方法") def__new__(cls): print("这是 new 方法") return object.\_\_new__(cls)
A()

总结

1、__new__至少要有一个参数cls,代表要实例化的类,此参数在实例化时由Python解释器自动提供
2、__new__必须要有返回值,返回实例化出来的实例,这点在自己实现__new__时要特别注意,可以return 父类.__new__(cls)出来的实例,或者直接是object的__new__出来的实例
3、__init__有一个参数self,就是这个__new__返回的实例,__init__在__new__的基础上可以完成一些其它初始化的动作,__init__不需要返回值
4、我们可以将类比作制造商,__new__方法就是前期的原材料购买环节,__init__方法就是在有原材料的基础上,加工,初始化商品环节
注意点

特殊方法名 默认的参数 功能描述
__init__() self 已经创建了对象,初始化对象回调方法
__str__() self 和toString
__del__() self 对象回收时候回调
__new__() cls 对象创建的回调方法

4、__del__() 方法
创建对象后,python解释器默认调用 __init__() 方法;
当删除一个对象时,python解释器也会默认调用一个方法,这个方法为 __del__() 方法
当内存中构建一个对象数据的时候回调 __init__() 方法,
当内存中销毁(释放)一个对象时回调 __del__() 方法

import time
class Animal(object):
# 初始化方法
# 创建完对象后会自动被调用def__init__(self, name): print('\_\_init__方法被调用') self.__name = name
# 当对象被删除时,会自动被调用def__del__(self): print("\_\_del__方法被调用") print("%s对象马上被干掉了..."%self.__name)
# 创建对象
dog = Animal("哈皮狗")
# 删除对象
del dog
cat = Animal("波斯猫")
cat2 = cat
cat3 = cat
print("---马上 删除cat对象")
del cat
print("---马上 删除cat2对象")
del cat2
print("---马上 删除cat3对象")
del cat3
print("程序2秒钟后结束")
time.sleep(2)

总结
1、当有 1 个变量保存了对象的引用时,此对象的引用计数就会加 1
2、当使用 del 删除变量指向的对象时,如果对象的引用计数不是 1,比如 3,那么此时只会让这个引用计数减 1,即变为 2,当再次调用 del 时,变为 1,如果再调用 1 次 del,此时会真的把对象进行删除
5、"魔法"方法
1、打印 id()
如果把 BMW 使用 print 进行输出的话,会看到如下的信息
即看到的是创建出来的 BMW 对象在内存中的地址
2、定义__str__()方法

classCar:def__init__(self, newWheelNum, newColor): self.wheelNum = newWheelNum self.color = newColor def__str__(self): msg = "嘿,我的颜色是" + self.color + "我有" + str(self.wheelNum) + "个轮胎..."return msg def move(self): print('车在跑,目标:夏威夷')
BMW = Car(4, "白色")
print(BMW)

总结
1、在python中方法名如果是__xxxx__()的,那么就有特殊的功能,因此叫做“魔法”方法
2、当使用print输出对象的时候,只要自己定义了__str__(self)方法,那么就会打印从在这个方法中return的数据

保护对象的属性

如果有一个对象,当需要对其进行修改属性时,有2种方法对象名.属性名 = 数据 ---->直接修改对象名.方法名() ---->间接修改
为了更好的保存属性安全,即不能随意修改,一般的处理方式为将属性定义为私有属性添加一个可以调用的方法,供调用
class People(object):def \_\_init__(self, name): self.__name = name def getName(self):return self.__name def setName(self, newName):if len(newName) >= 5: self.__name = newName else: print("error:名字长度需要大于或者等于5")
xiaoming = People("bin")
print(xiaoming.__name)

Class People(object):Def \_\_init__(self, name): self.__name = name def getName(self):return self.__name def setName(self, newName):if len(newName) >= 5: self.__name = newName else: print("error:名字长度需要大于或者等于5")
xiaoming = People("bin")
xiaoming.setName("wanger")
print(xiaoming.getName())
xiaoming.setName("lisi")
print(xiaoming.getName())


总结

1、Python 中没有像 C++ 中 public 和 private 这些关键字来区别公有属性和私有属性
2、它是以属性命名方式来区分,如果在属性名前面加了 2 个下划线 ‘__’ ,则表明该属性是私有属性,否则为公有属性(方法也是一样,方法名前面加了2个下划线的话表示该方法是私有的,否则为公有的)。

继承

  1. 继承的概念
    在现实生活中,继承一般指的是子女继承父辈的财产,如下图
    在程序中,继承描述的是事物之间的所属关系,例如猫和狗都属于动物,程序中便可以描述为猫和狗继承自动物;同理,波斯猫和巴厘猫都继承至猫,而沙皮狗和斑点狗都继承至狗,如下如所示:
  2. 继承示例
# 定义一个父类,如下:
class Cat(object):def __init__(self, name, color="白色"):self.name = nameself.color = colordef run(self):print("%s--在跑"%self.name)
# 定义一个子类,继承Cat类,如下:
class Bosi(Cat):def setNewName(self, newName):self.name = newNamedef eat(self):print("%s--在吃"%self.name)
bs = Bosi("波斯猫")
print('bs的名字为:%s'%bs.name)
print('bs的颜色为:%s'%bs.color)
bs.eat()
bs.setNewName('波斯1号')
bs.run()

说明:

虽然子类没有定义 __init__ 方法,但是父类有,所以在子类继承父类的时候这个方法就被继承了,所以只要创建 Bosi 的对象,就默认执行了那个继承过来的 __init__ 方法

总结

1、子类在继承的时候,在定义类时,小括号()中为父类的名字
2、父类的属性、方法,会被继承给子类

  1. 注意点
class Animal(object):def \_\_init__(self, name='动物', color='白色'):self.__name = nameself.color = colordef __test(self):print(self.__name)print(self.color)def test(self):print(self.__name)print(self.color)
class Dog(Animal):def dogTest1(self):#print(self.__name)#不能访问到父类的私有属性print(self.color)def dogTest2(self):#self.__test()#不能访问父类中的私有方法self.test()
a = Animal()
#print(a.__name)
#程序出现异常,不能访问私有属性
print(a.color)
#a.__test()
#程序出现异常,不能访问私有方法
a.test()
print("------分割线-----")
d = Dog(name = "小花狗", color = "黄色")
d.dogTest1()
d.dogTest2()

1、私有的属性,不能通过对象直接访问,但是可以通过方法访问
2、私有的方法,不能通过对象直接访问
3、私有的属性、方法,不会被子类继承,也不能被访问
4、一般情况下,私有的属性、方法都是不对外公布的,往往用来做内部的事情,起到安全的作用

多继承

  1. 多继承
    从图中能够看出,所谓多继承,即子类有多个父类,并且具有它们的特征
    Python 中多继承的格式如下:
# 定义一个父类
class A:def printA(self):print('----A----')
# 定义一个父类
class B:def printB(self):print('----B----')# 定义一个子类,继承自A、B
class C(A,B):def printC(self):print('----C----')
obj_C = C()
obj_C.printA()
obj_C.printB()
obj_C.printC()

运行结果:

----A----
----B----
----C----

说明:

1、python中是可以多继承的
2、父类中的方法、属性,子类会继承

注意点:
想一想:
如果在上面的多继承例子中,如果父类A和父类B中,有一个同名的方法,那么通过子类去调用的时候,调用哪个?

#coding=utf-8
class base(object):def test(self):print('----base test----')
class A(base):def test(self):print('----A test----')
# 定义一个父类
class B(base):def test(self):print('----B test----')
# 定义一个子类,继承自A、B
class C(A,B):pass
obj_C = C()
obj_C.test()
print(C.__mro__)
#可以查看C类的对象搜索方法时的先后顺序,C3算法得到一个元组

2、重写
<1>重写父类方法
所谓重写,就是子类中,有一个和父类相同名字的方法,在子类中的方法会覆盖掉父类中同名的方法

#coding=utf-8
class Cat(object): def sayHello(self): print("halou-----1")
class Bosi(Cat): def sayHello(self): print("halou-----2")
bosi = Bosi()
bosi.sayHello()

<2> 调用父类的方法

#coding=utf-8
class Cat(object): def __init__(self,name): self.name = name self.color = 'yellow'
class Bosi(Cat): def __init__(self,name): # 调用父类的__init__方法1(python2) #Cat.__init__(self,name) # 调用父类的__init__方法2 #super(Bosi,self).__init__(name) # 调用父类的__init__方法3 super().__init__(name) #推荐def getName(self): return self.name
bosi = Bosi('xiaohua')
print(bosi.name)
print(bosi.color)

多态

多态的概念是应用于Java和C#这一类强类型语言中,而Python崇尚“鸭子类型”。
所谓多态:定义时的类型和运行时的类型不一样,此时就成为多态

class F1(object):def show(self):print('F1.show')
class S1(F1):def show(self):print('S1.show')
class S2(F1):def show(self):print('S2.show')
# 由于在Java或C#中定义函数参数时,必须指定参数的类型# 为了让Func函数既可以执行S1对象的show方法,又可以执行S2对象的show方法,所以,定义了一个S1和S2类的父类# 而实际传入的参数是:S1对象和S2对象
def func(obj):"""Func函数需要接收一个F1类型或者F1子类的类型"""obj.show()
s1_obj = S1()
func(s1_obj) # 在Func函数中传入S1类的对象 s1_obj,执行 S1 的show方法,结果:S1.show
s2_obj = S2()
func(s2_obj)# 在Func函数中传入Ss类的对象 ss_obj,执行 Ss 的show方法,结果:S2.show

Python 伪代码实现 Java 或 C# 的多态

类属性与实例属性

在了解了类基本的东西之后,下面看一下 python 中这几个概念的区别
先来谈一下类属性和实例属性
在前面的例子中我们接触到的就是实例属性(对象属性),顾名思义,类属性就是类对象所拥有的属性,它被所有类对象的实例对象所共有,在内存中只存在一个副本,这个和 C++,java 中类的静态成员变量有点类似。对于公有的类属性,在类外可以通过类对象和实例对象访问。

类属性:所属类,这个类下所有的对象都可以共享这个类属性。 相当于 java 中静态属性。

比如:

Class   Person{public static  String  name="abc"
}

1、类属性

class People(object): name = 'Tom'#公有的类属性 __age = 12#私有的类属性
p = People()
print(p.name) #正确
print(People.name) #正确
print(p.__age) #错误,不能在类外通过实例对象访问私有的类属性
print(People.__age) #错误,不能在类外通过类对象访问私有的类属性

2、实例属性(对象属性)

Class People(object): address = '山东'#类属性def__init__(self): self.name = 'xiaowang'#实例属性 self.age = 20#实例属性
p = People()
p.age =12#实例属性
print(p.address) #正确
print(p.name) #正确
print(p.age) #正确
print(People.address) #正确
print(People.name) #错误
print(People.age) #错误

3、通过实例(对象)去修改类属性

classPeople(object): country = 'china'#类属性
print(People.country) #china
p = People()
print(p.country) #china
p.country = 'japan'
print(p.country) #实例属性会屏蔽掉同名的类属性
print(People.country) #china
del p.country #删除实例属性
print(p.country) #china

总结

  如果需要在类外修改类属性,必须通过类对象去引用然后进行修改。如果通过实例对象去引用,会产生一个同名的实例属性,这种方式修改的是实例属性,不会影响到类属性,并且之后如果通过实例对象去引用该名称的属性,实例属性会强制屏蔽掉类属性,即引用的是实例属性,除非删除了该实例属性。

属性叫法 变量叫法 描述
类属性(私有和公有) 类变量 所有对象共享同一份类属性。
实例属性(私/公) 成员变量 每个不同对象,有不一样值的实例属性

类方法和静态方法

  1. 类方法
    是类对象所拥有的方法,需要用修饰器 @classmethod 来标识其为类方法,对于类方法,第一个参数必须是类对象,一般以 cls 作为第一个参数(当然可以用其他名称的变量作为其第一个参数,但是大部分人都习惯以 ‘cls’ 作为第一个参数的名字,就最好用 ‘cls’ 了),能够通过实例对象和类对象去访问。
class People(object): country = 'china'#类方法,用classmethod来进行修饰  @classmethoddef getCountry(cls):return cls.country
p = People()
print(p.getCountry()) #可以用过实例对象引用
print(People.getCountry()) #可以通过类对象引用

类方法还有一个用途就是可以对类属性进行修改:

classPeople(object): country = 'china'#类方法,用classmethod来进行修饰 @classmethoddef getCountry(cls):return cls.country @classmethoddef setCountry(cls,country): cls.country = country
p = People()
print p.getCountry() #可以用过实例对象引用
print People.getCountry() #可以通过类对象引用
p.setCountry('japan')
print p.getCountry()
print People.getCountry()

结果显示在用类方法对类属性修改之后,通过类对象和实例对象访问都发生了改变
2. 静态方法
需要通过修饰器 @staticmethod 来进行修饰,静态方法不需要多定义参数

classPeople(object): country = 'china' @staticmethod#静态方法def getCountry():return People.country
print People.getCountry()

总结
从类方法和实例方法以及静态方法的定义形式就可以看出来,类方法的第一个参数是类对象 cls,那么通过 cls 引用的必定是类对象的属性和方法;而实例方法的第一个参数是实例对象 self,那么通过 self 引用的可能是类属性、也有可能是实例属性(这个需要具体分析),不过在存在相同名称的类属性和实例属性的情况下,实例属性优先级更高。静态方法中不需要额外定义参数,因此在静态方法中引用类属性的话,必须通过类对象来引用

方法类别 语法 描述
类方法 @classmethod 第一个形参 cls。默认传递
静态方法 @staticmethod 没有默认传递的形参
对象方法(成员方法) def 方法名 第一个形参 self ,默认传递

第八章设计模式

单例模式

  1. 单例是什么
    举个常见的单例模式例子,我们日常使用的电脑上都有一个回收站,在整个操作系统中,回收站只能有一个实例,整个系统都使用这个唯一的实例,而且回收站自行提供自己的实例。因此回收站是单例模式的应用。
    确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类,单例模式是一种对象创建型模式。
  2. 创建单例 - 保证只有 1 个对象
# 实例化一个单例
Class Singleton(object):__instance = None
def__new__(cls, age, name):#如果类数字能够__instance没有或者没有赋值#那么就创建一个对象,并且赋值为这个对象的引用,保证下次调用这个方法时#能够知道之前已经创建过对象了,这样就保证了只有1个对象If cls.__instance==None: cls.__instance = object.__new__(cls) return cls.__instance
a = Singleton(18, "bin")
b = Singleton(8, "bin")
print(id(a))
print(id(b))
a.age = 19#给a指向的对象添加一个属性
print(b.age)#获取b指向的对象的age属性

运行结果:

In [12]: class Singleton(object):
...: __instance = None
...:
...: def__new__(cls, age, name):
...: if not cls.__instance:
...: cls.__instance = object.__new__(cls)
...: return cls.__instance
...:
...: a = Singleton(18, "bin")
...: b = Singleton(8, "bin")
...:
...: print(id(a))
...: print(id(b))
...:
...: a.age = 19
...: print(b.age)
...: 4391023224439102322419
  1. 创建单例时,只执行 1 次 __init__ 方法
# 实例化一个单例
classSingleton(object): __instance = None __first_init = False
def__new__(cls, age, name):if not cls.__instance: cls.__instance = object.__new__(cls) return cls.__instance
def__init__(self, age, name):if not self.__first_init: self.age = age self.name = name self.__first_init = True
a = Singleton(18, "bin")
b = Singleton(8, "tom")
print(id(a))
print(id(b))
print(a.age) #18
print(b.age) #18
a.  age = 19
b.  print(b.age)#19

工厂模式

  工厂模式是我们最常用的实例化对象模式了,是用工厂方法代替 new 操作的一种模式。虽然这样做,可能多做一些工作,但会给你系统带来更大的可扩展性和尽量少的修改量(可维护性)。
  1、简单工厂模式
  Simple Factory 模式不是独立的设计模式,他是 Factory Method 模式的一种简单的、特殊的实现。他也被称为静态工厂模式,通常创建者的创建方法被设计为 static 方便调用。

1、静态的工厂类
2、用全局函数改写工厂类

class Axe(object):def cut_tree(self):print("斧头开始砍树了")
class StoneAxe(Axe):def cut_tree(self):print("使用石头做的斧头开始砍树")
class SteelAxe(Axe):def cut_tree(self):print("使用钢铁做的斧头开始砍树")
class Factory(object):#根据用户指定的类型创建对应类的对象@staticmethoddef create_axe(type):if type=="stone":return StoneAxe()elif type == "steel":return SteelAxe()else:print("传入的参数类型不对")class Person(object):def __init__(self,name):self.name = name# def work(self,axe_type):#     print(self.name+"开始工作了")#     if axe_type=="stone":#         axe =  StoneAxe()#     elif axe_type=="steel" :#         axe = SteelAxe()#     else:#         print("类型不正确...")#         return#     axe.cut_tree()def work(self,type):print("%s开始工作了"%self.name)axe = Factory.create_axe("steel")axe.cut_tree()
p = Person("农夫")
p.work("steel")

第九章 异常

异常简介

看如下示例:

print'-----test--1---'
open('123.txt','r')
print'-----test--2---'

运行结果:
说明:
打开一个不存在的文件 123.txt,当找不到 123.txt 文件时,就会抛出给我们一个 FileNotFoundError 类型的错误,No such file or directory:123.txt (没有123.txt这样的文件或目录)
异常:
当 Python 检测到一个错误时,解释器就无法继续执行了,反而出现了一些错误的提示,这就是所谓的"异常"

捕获异常

<1>捕获异常 try...except...
看如下示例:

try:print('-----test--1---') open('123.txt','r') print('-----test--2---')
except IOError: pass

说明:
此程序看不到任何错误,因为用 except 捕获到了 IOError 异常,并添加了处理的方法
pass 表示实现了相应的实现,但什么也不做;如果把 pass 改为 print 语句,那么就会输出其他信息
小总结:
把可能出现问题的代码,放在 try 中
把处理异常的代码,放在 except 中
<2>except 捕获多个异常
看如下示例:

try: print(num)
except IOError: print('产生错误了')

想一想:
上例程序,已经使用 except 来捕获异常了,为什么还会看到错误的信息提示?
答:
except 捕获的错误类型是 IOError,而此时程序产生的异常为 NameError ,所以 except 没有生效
修改后的代码为:

try: print num
except NameError: print('产生错误了')

实际开发中,捕获多个异常的方式,如下:

#coding=utf-8
try: print('-----test--1---') open('123.txt','r') # 如果123.txt文件不存在,那么会产生 IOError 异常 print('-----test--2---') print(num)# 如果num变量没有定义,那么会产生 NameError 异常
except (IOError,NameError) as errorMsg: #如果想通过一次except捕获到多个异常可以用一个元组的方式# errorMsg里会保存捕获到的错误信息 print(errorMsg)


注意:
当捕获多个异常时,可以把要捕获的异常的名字,放到except 后,并使用元组的方式仅进行存储
<3>获取异常的信息描述<4>捕获所有异常
<5> else
咱们应该对 else 并不陌生,在if中,它的作用是当条件不满足时执行的实行;同样在 try…except… 中也是如此,即如果没有捕获到异常,那么就执行 else 中的事情

try: num = 100print num
except NameError as errorMsg: print('产生错误了:%s'%errorMsg)
else: print('没有捕获到异常,真高兴')

运行结果如下:
<6> try...finally...
try…finally… 语句用来表达这样的情况:
在程序中,如果一个段代码必须要执行,即无论异常是否产生都要执行,那么此时就需要使用 finally。 比如文件关闭,释放锁,把数据库连接返还给连接池等

异常的传递

  1. try嵌套中
import time try: f = open('test.txt') try: while True: content = f.readline() if len(content) == 0: break time.sleep(2) print(content) finally: f.close() print('关闭文件')
except: print("没有这个文件")

运行结果:

In [26]: import time
...: try:
...: f = open('test.txt')
...: try:
...: while True:
...: content = f.readline()
...: if len(content) == 0:
...: break
...: time.sleep(2)
...: print(content)
...: finally:
...: f.close()
...: print('关闭文件')
...: except:
...: print("没有这个文件")
...: finally:
...: print("最后的finally")
...: xxxxxxx--->这是test.txt文件中读取到信息 ^C关闭文件 没有这个文件 最后的finally
  1. 函数嵌套调用中
def test1(): print("----test1-1----") print(num) print("----test1-2----")
def test2(): print("----test2-1----") test1() print("----test2-2----")
def test3():try: print("----test3-1----") test1() print("----test3-2----") except Exception as result: print("捕获到了异常,信息是:%s"%result)
print("----test3-2----")
test3()
print("------华丽的分割线-----")
test2()

运行结果:
总结:
  如果 try 嵌套,那么如果里面的 try 没有捕获到这个异常,那么外面的 try 会接收到这个异常,然后进行处理,如果外边的 try 依然没有捕获到,那么再进行传递。。。
  如果一个异常是在一个函数中产生的,例如函数 A---->函数 B---->函数 C,而异常是在函数 C中产生的,那么如果函数 C中没有对这个异常进行处理,那么这个异常会传递到函数 B中,如果函数 B有异常处理那么就会按照函数 B的处理方式进行执行;如果函数 B也没有异常处理,那么这个异常会继续传递,以此类推。。。如果所有的函数都没有处理,那么此时就会进行异常的默认处理,即通常见到的那样
  注意观察上图中,当调用 test3 函数时,在 test1 函数内部产生了异常,此异常被传递到 test3 函数中完成了异常处理,而当异常处理完后,并没有返回到函数 test1 中进行执行,而是在函数 test3 中继续执行

自定义异常

你可以用 raise 语句来引发一个异常。异常/错误对象必须有一个名字,且它们应是 Error 或 Exception 类的子类
下面是一个引发异常的例子:

# 自定义异常类
class ShortInputException(Exception):def __init__(self,length,atleast):self.length = lengthself.atleast = atleastdef __str__(self):return "[Length Error]长度不足%d,您输入字符串的长度是%d"%(self.atleast,self.length)
def test():try:name =  input("请输入用户名称(至少是6字符):")if len(name) < 6:raise ShortInputException(len(name),6)except ShortInputException as msg:print(msg)
test()

注意
  以上程序中,关于代码#super().__init__()的说明
  这一行代码,可以调用也可以不调用,建议调用,因为__init__方法往往是用来对创建完的对象进行初始化工作,如果在子类中重写了父类的__init__方法,即意味着父类中的很多初始化工作没有做,这样就不保证程序的稳定了,所以在以后的开发中,如果重写了父类的__init__方法,最好是先调用父类的这个方法,然后再添加自己的功能

异常处理中抛出异常(扩展)

class Test(object):def __init__(self, switch): self.switch = switch #开关def calc(self, a, b):try: return a/b except Exception as result: if self.switch: print("捕获开启,已经捕获到了异常,信息如下:") print(result) else: #重新抛出这个异常,此时就不会被这个异常处理给捕获到,从而触发默认的异常处理raise
a = Test(True)
a.calc(11,0)
print("----------------------华丽的分割线----------------")
a.switch = False
a.calc(11,0)

总结:

try:是异常捕获开始代码,try放在特别关心的那段代码前面pass:如果这行代码出现了异常,那么后面的代码不会运行pass2pass3
except 异常的类型 as ex: 捕获某种类型的异常
except....多个except。按照顺序依次比对类型
else:没有异常时执行
finally:不管有没有异常都会执行

第十章 Python 模块及安装

模块的使用及安装

<1>Python 中的模块
在 Python 中有一个概念叫做模块(module),这个和 C 语言中的头文件以及Java 中的jar包很类似,比如在 Python 中要调用 sqrt 函数,必须用 import 关键字引入 math 这个模块,下面就来了解一下 Python 中的模块。
说的通俗点:模块就好比是工具包,要想使用这个工具包中的工具(就好比函数),就需要导入这个模块
<2>import
在 Python 中用关键字 import 来引入某个模块,比如要引用模块 math,就可以在文件最开始的地方用 import math 来引入。
形如:

import module1,mudule2...

当解释器遇到 import 语句,如果模块在当前的搜索路径就会被导入。
在调用 math 模块中的函数时,必须这样引用:

import math
print(math.sqrt(2))
import math as m
print(m.sqrt(2))

有时候我们只需要用到模块中的某个函数,只需要引入该函数即可,此时可以用下面方法实现:
<3>from…import
Python 的 from 语句让你从模块中导入一个指定的部分到当前命名空间中
语法如下:

from modname import name1[, name2[, ... nameN]]

例如,要导入模块 math 的 sqrt 函数,使用如下语句:

from math  import sqrt

注意:不会把整个 math 模块导入到当前的命名空间中,它只会将 math 里的 sqrt 单个引入
<4>from … import *
把一个模块的所有内容全都导入到当前的命名空间也是可行的,只需使用如下声明:

from modname import *

注意:这提供了一个简单的方法来导入一个模块中的所有项目。然而这种声明不该被过多地使用。

from math import *

<5>定位模块
当你导入一个模块,Python 解析器对模块位置的搜索顺序是:
1、当前目录
2、如果不在当前目录,Python 则搜索在 shell 变量PYTHONPATH下的每个目录。
3、如果都找不到,Python 会察看默认路径。UNIX 下,默认路径一般为/usr/local/lib/python/
<6>安装模块

conda install 模块
pip install 模块
pymysql
numpy

卸载模块:

pip uninstall 模块
conda uninstall 模块

模块制作

<1>定义自己的模块
在Python中,每个Python文件都可以作为一个模块,模块的名字就是文件的名字。
比如有这样一个文件 test.py,在 test.py 中定义了函数 add
test.py

def add(a,b): return a+b

<2>调用自己定义的模块
那么在其他文件中就可以先 import test,然后通过 test.add(a,b) 来调用了,当然也可以通过 from test import add 来引入
main.py

import test
result = test.add(11,22)
print(result)

<3>测试模块
在实际开中,当一个开发人员编写完一个模块后,为了让模块能够在项目中达到想要的效果,这个开发人员会自行在 py 文件中添加一些测试信息,例如:
test.py

def add(a,b): return a+b # 用来进行测试
ret = add(12,22)
print('int test.py file,,,,12+22=%d'%ret)

如果此时,在其他py文件中引入了此文件的话,想想看,测试的那段代码是否也会执行呢!
main.py

import test
result = test.add(11,22)
print(result)

至此,可发现 test.py 中的测试代码,应该是单独执行 test.py 文件时才应该执行的,不应该是其他的文件中引用而执行
为了解决这个问题,python 在执行一个文件时有个变量 __name__

总结:
可以根据 __name__变量的结果能够判断出,是直接执行的 python 脚本还是被引入执行的,从而能够有选择性的执行测试代码
test.py

def add(a,b): return a+b # 用来进行测试 if __name__=='__main__':ret = add(12,22) print('int test.py file,,,,12+22=%d'%ret)

<4>模块中的 __all__ 作用是,from xx import *的时候,防止导入过多的函数,把导入的限制在 __all__中
test.py
__all__=[“add”]

Python中的模块

1、python中的包

  1. 引入包
    1.1 包就是一个目录
    1.2 把多个py文件放到同一个文件夹下
    1.3 使用import 文件夹.模块 的方式导入
    python3可以导入包,python2不行。
    1.4 使用from 文件夹 import 模块 的方式导入
    python3可以导入包,python2不行。
    1.5 在包的文件夹下创建__init__.py文件。
    在python2中:有一个目录,并且目录下有一个__init__.py的文件。才叫包。
    虽然文件内容没有,但是python2可以用了
    有__init__.py文件在python3中没有有错。以后我们都在包的目录下新建一个init文件。
    1.6 在__init__.py文件中写入
    from . import 模块1
    from . import 模块2
    那么可以使用import 文件夹 导入
    1.7 也可以使用from 文件夹 import 模块 的方式导入
    总结:
    包将有联系的模块组织在一起,即放到同一个文件夹下,并且在这个文件夹创建一个名字为__init__.py 文件,那么这个文件夹就称之为包
    有效避免模块名称冲突问题,让应用组织结构更加清晰
  2. __init__.py文件有什么用(扩展)
    __init__.py 控制着包的导入行为
    2.1 __init__.py为空
    仅仅是把这个包导入,不会导入包中的模块
    2.2 (了解)可以在__init__.py文件中编写内容
    可以在这个文件中编写语句,当导入时,这些语句就会被执行
    __init__.py文件

第十一章 列表推导式

1、所谓的列表推导式,就是指的轻量级循环创建列表:

a = [i for i in range(1,10)]# [1, 2, 3, 4, 5, 6, 7, 8, 9]
b= [11 for i in range(1,10)]# [11, 11, 11, 11, 11, 11, 11, 11, 11]

2、在循环的过程中使用 if 来确定 列表中元素的条件

a = [i for i in range(1,10) if i%2==0] # [2, 4, 6, 8]
c = [i for i in range(1,10) if i%2==0 if i>5]# [6, 8]

3、2个for循环

a=[(i,j) for i in range(1,5) for j in range(6,10)]

4、3个for循环

a= [(x,y,z) for x in range(2) for y in range(2) for z in range(2)]

python 中的数据库操作

pymysql 的使用
pymysql 的文档地址:
https://pymysql.readthedocs.io/en/latest/
使用 conda 安装:conda install pymysql

conda install 模块
pip install 模块
pymysql

卸载模块:

pip uninstall 模块
conda uninstall 模块

由于 conda 默认的镜像使用的国外的,容易出现链接不上的情况:
打开:

输入命令:conda config --show-sources

修改该文件:

channels:- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/r- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/pro- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/msys2
ssl_verify: true
show_channel_urls: true

重启
,输出命令:

conda install pymysql
conda install numpy

创建数据库:

from pymysql import *# 建立到数据库的连接
conn = connect(host='192.168.20.61', user='root', password='123456')
# 获取游标
mycur = conn.cursor()
# 执行创建数据库的语句
rowNum = mycur.execute("create database pydb")print("受影响的行数:", rowNum)# 关闭游标
mycur.close()
# 关闭连接
conn.close()

创建数据库表:

from pymysql import *# 建立到数据库的连接
conn = connect(host='192.168.20.61', user='root', password='123456', database='pydb')
# 获取游标
mycur = conn.cursor()
# 执行创建数据库的语句
rowNum = mycur.execute("""
CREATE TABLE `tb_user` (`id` bigint(20) NOT NULL AUTO_INCREMENT,`username` varchar(50) NOT NULL COMMENT '用户名',`password` varchar(32) NOT NULL COMMENT '密码,加密存储',`phone` varchar(20) DEFAULT NULL COMMENT '注册手机号',`email` varchar(50) DEFAULT NULL COMMENT '注册邮箱',`created` datetime NOT NULL,`updated` datetime NOT NULL,PRIMARY KEY (`id`),UNIQUE KEY `username` (`username`) USING BTREE,UNIQUE KEY `phone` (`phone`) USING BTREE,UNIQUE KEY `email` (`email`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=37 DEFAULT CHARSET=utf8 COMMENT='用户表'
""")print("受影响的行数:", rowNum)# 关闭游标
mycur.close()
# 关闭连接
conn.close()

新增数据:

 from pymysql import *# 建立到数据库的连接
conn = connect(host='192.168.20.61', user='root', password='123456', database='pydb')
# 获取游标
mycur = conn.cursor()
# 开启事务
conn.begin()
# 执行创建数据库的语句
rowNum = mycur.execute('''
INSERT INTO `tb_user` VALUES (1, 'lisi', 'e10adc3949ba59abbe56e057f20f883e', '13488888888','aa@a', '2019-12-25 17:03:55', '2019-12-24 17:03:55');
''')
# 防止SQL注入,%s是占位符,不是python的
rowNum1 = mycur.execute('''
INSERT INTO `tb_user` VALUES (%s, %s, %s, %s, %s, %s, %s);
''', (2, 'test02', '202cb962ac59075b964b07152d234b70', '1370348890', None, '2019-08-01 12:28:39', '2019-08-01 12:28:39'))rowNum2 = mycur.execute('''
INSERT INTO tb_user(username,password,phone,email,created,updated) VALUES (%s, %s, %s, %s, %s, %s);
''', ( 'wangwu', 'e10adc3949ba59abbe56e057f20f883e', '13488888889','aa@126.com', '2019-12-25 17:03:55', '2019-12-24 17:03:55'))
row =  rowNum+rowNum1+rowNum2
print("受影响的行数:",row)
if row==3:# 提交事务conn.commit()
else:conn.rollback()# 关闭游标
mycur.close()
# 关闭连接
conn.close()

删除数据:

from pymysql import *# 建立到数据库的连接
conn = connect(host='192.168.20.61', user='root', password='123456', database='pydb')
# 获取游标
mycur = conn.cursor()
# 开启事务
conn.begin()
# 执行创建数据库的语句
# 防止SQL注入
rowNum = mycur.execute('delete from tb_user where id=%s', (37,))print("受影响的行数:", rowNum)
# 提交事务
conn.commit()# 关闭游标
mycur.close()
# 关闭连接
conn.close()

查询:

from pymysql import *# 建立到数据库的连接
conn = connect(host='192.168.20.61', user='root', password='123456', database='pydb')
# 获取游标
mycur = conn.cursor()
# 执行查询,返回受影响的行数
rowNum = mycur.execute("select * from tb_user")print("受影响的行数:", rowNum)
# 获取所有结果
results = mycur.fetchall()
print(type(results))
# 遍历结果集
for result in results:print(result)#print(result[0],result[1])
# 关闭游标
mycur.close()
# 关闭连接
conn.close()

Numpy

Numpy 是什么?

NumPy(Numerical Python的缩写)是一个开源的Python科学计算库。使用NumPy,就可以很自然地使用数组和矩阵(https://baike.baidu.com/item/%E7%9F%A9%E9%98%B5/18069?fr=aladdin)。 NumPy包含很多实用的数学函数,涵盖线性代数运算、傅里叶变换和随机数生成等功能。
这个库的前身是1995年就开始开发的一个用于数组运算的库。经过了长时间的发展,基本上成了绝大部分Python科学计算的基础包,当然也包括所有提供Python接口的深度学习框架。

为什么使用 Numpy?

a) 便捷:
对于同样的数值计算任务,使用NumPy要比直接编写Python代码便捷得多。这是因为NumPy能够直接对数组和矩阵进行操作,可以省略很多循环语句,其众多的数学函数也会让编写代码的工作轻松许多。

b) 性能:
NumPy中数组的存储效率和输入输出性能均远远优于Python中等价的基本数据结构(如嵌套的list容器)。其能够提升的性能是与数组中元素的数目成比例的。对于大型数组的运算,使用NumPy的确很有优势。对于TB级的大文件,NumPy使用内存映射文件来处理,以达到最优的数据读写性能。

c) 高效:
NumPy的大部分代码都是用C语言写成的,这使得NumPy比纯Python代码高效得多。

  当然,NumPy也有其不足之处,由于NumPy使用内存映射文件以达到最优的数据读写性能,而内存的大小限制了其对TB级大文件的处理;此外,NumPy数组的通用性不及Python提供的list容器。因此,在科学计算之外的领域,NumPy的优势也就不那么明显。

Numpy 的安装:

(1) 官网安装。http://www.numpy.org/。
(2) pip 安装。pip install numpy。
(3) Anaconda安装(推荐),Anaconda里面集成了很多关于python科学计算的第三方库,主要是安装方便。下载地址:https://www.anaconda.com/download/。
    conda install numpy

numpy 基础:

  NumPy 的主要对象是同种元素的多维数组。这是一个所有的元素都是一种类型。在 NumPy 中维度 (dimensions) 叫做轴 (axes),轴的个数叫做秩 (rank)。NumPy 的数组类被称作 ndarray(矩阵也叫数组) 。通常被称作数组。常用的 ndarray 对象属性有:ndarray.ndim (数组轴的个数,轴的个数被称作秩),ndarray.shape (数组的维度。这是一个指示数组在每个维度上大小的整数元组。例如一个 n 行 m 列的矩阵,它的 shape 属性将是 (2,3),这个元组的长度显然是秩,即维度或者 ndim 属性),ndarray.size(数组元素的总个数,等于 shape 属性中元组元素的乘积),ndarray.dtype(一个用来描述数组中元素类型的对象,可以通过创造或指定 dtype 使用标准 Python 类型。另外 NumPy 提供它自己的数据类型)。
Numpy 的数据类型:
例1:

import numpy as np
print(np.float32)
print(np.int64)
print(np.int32)
a = np.dtype(np.int_)
print(a)

Numpy 内置的特征码:
int8, int16, int32, int64 可以由字符串 ’i1’, ‘i2’, ’i4’, ‘i8’ 代替,其余的以此类推。

例2:

import numpy as np
a = np.dtype('i4')    # ’f8’, ‘i4’,’a30’(30个字符的字
# 符串),…
print (a)

创建数组并查看其属性:

(1) 用 np.array 从 python 列表和元组创建数组:
例3:

import numpy as np#array= np.array([1,2,3])
array= np.array([[1,2,3],[4,5,6]],dtype=int)
print(array)
print("ndim:%d"%array.ndim)
print("shape:%s"%str(array.shape))
print("size:%d"%array.size)
print("dtype:%s"%array.dtype)


例4:

import numpy as nparray= np.array([[1,2,3],[4,5,6]],dtype= float)
print(array)
print("ndim:%d"%array.ndim)
print("shape:%s"%str(array.shape))
print("size:%d"%array.size)
print("dtype:%s"%array.dtype)

思考该数组的各个参数值分别多少?

array=np.array([[[1,2],[3,4]],[[5,6],[7,8]],[[9,10],[11,12]]])

(2) 用 np.arange().reshape() 创建数组:
例5:

import numpy as np
array = np.arange(10).reshape(2,5)
# 创建2行5列的二维数组,
# 也可以创建三维数组,
# array = np.arange(12).reshape(2,3,2)
print(array)
print("ndim:%d"%array.ndim)
print("shape:%s"%str(array.shape))
print("size:%d"%array.size)
print("dtype:%s"%array.dtype)


判断下列三维数组的 shape:

a = np.array([[[1,2,3], [4, 5, 6], [7, 8, 9]]])#(1,3,3)
b = np.array([[[1,2,3]], [[4, 5, 6]], [[7, 8, 9]]])#(3,1,3)

答案:a->(1,3,3) b->(3,1,3)

使用随机数创建:

例6:

import numpy as np
#randint(low, high=None, size=None, dtype='l')
array = np.random.randint(1,10,24).reshape(2,3,4)#均匀分布:随机数范围[0, 1)
# array = np.random.rand(9).reshape(3,3)
# array = np.random.rand(3,3)
#标准正态分布随机数:可以为负数
#array = np.random.randn(3,3)
print(array)
print("ndim:%d"%array.ndim)
print("shape:%s"%str(array.shape))
print("size:%d"%array.size)
# Numpy 随机数模块 np.random.randint, np.random.randn, np.random.rand 的比较


(1)rand 生成均匀分布的伪随机数。分布在 [0,1) 之间
(2)randn 生成标准正态分布的伪随机数(均值为 0,方差为 1)。
例7:

import numpy as np
array = np.empty(9).reshape(3,3)
# array = np.empty([3,3])
# array = np.empty([3,3],dtype="int")
# array = np.ones([3,3])
# array = np.zeros([3,3])
print(array)
print("ndim:%d"%array.ndim)
print("shape:%s"%str(array.shape))
print("size:%d"%array.size)

常用函数:

例8:where()

import numpy as np
array = np.random.randint(1,10,9).reshape(3,3)
print(array)
print(np.where(array>5,array,0))
#获取某些元素值
print(array[2][2])



索引,切片和迭代:

例9:晚上

import numpy as np
#一维切片
a = np.arange(10)**3
print(a)
#获取第三个元素
print(a[2])
#获取第三到第五个元素
print(a[2:5])
#获取前6个中,从第一个开始,步长为2
print(a[0:6:2])
print(a[:6:2])#0省略了
#将他们的值改为-1000
a[:6:2] =-1000
print(a[:6:2])
#倒序获取
print(a[::-1])
#循环输出
for i in a:print(i,end="\t")
#二维切片
array = np.random.randint(1,10,24).reshape(4,6)
print(array)
# 获取第一行所有值
print(array[0])# 获取第一 列的所有值
print(array[::,0])
print(array[:,0])
# 获取第一和三行
print(array[0:4:2,])
# 获取第二列和第四列
print(array[::,1:4:2])
# 获取第一和三行的第二列和第四列
print(array[0:4:2,1:4:2])

2021-02-15 大数据课程笔记 day26相关推荐

  1. 2021-03-08~09~10~11~12 大数据课程笔记 day47day48day49day50day51

    @R星校长 大数据技术之Flink 第一章 初识Flink   在当前数据量激增的时代,各种业务场景都有大量的业务数据产生,对于这些不断产生的数据应该如何进行有效的处理,成为当下大多数公司所面临的问题 ...

  2. 2021-02-26~27~28 大数据课程笔记 day37day38day39

    @R星校长 音乐数据中心平台 1.1 数据库与ER建模 1.1.1 数据库(DataBase)   数据库是按照数据结构来组织.存储和管理数据的仓库,是一个长期存储在计算机内的.有组织的.可共享的.统 ...

  3. 大数据课程笔记3:Kolmogorov Complexity

    这是大数据算法的课程笔记,这节讲的是Kolmogorov Complexity的定义以及三个性质. 定义 先有个图灵机的定义,然后有了一个Universal Turing Machine (UTM)的 ...

  4. 数据结构大作业_大数据课程笔记

    前言: 到目前为止有了一个月的时间,学习了python基础及算法.常用计算库numpy和pandas数据的导入和各种处理.matplotlib和seaborn做数据可视化 以及上周的大数据框架hado ...

  5. 2021-03-17~18 大数据课程笔记 day56day57

    @R星校长 1 基础概念和Kylin简介 1.1 OLTP与OLAP   数据处理大致可以分成两大类:联机事务处理OLTP(on-line transaction processing).联机分析处理 ...

  6. 2021-02-12 大数据课程笔记 day23

    @R星校长 redis 概述 为什么使用 redis? 什么是 Redis? Redis是用C语言开发的一个开源的高性能键值对(key-value)内存数据库. 它提供六种数据类型来存储值:str ...

  7. 大数据学习02:大数据课程概述与大数据背景知识

    Hadoop2.X管理与开发 每日关注 2019年3月21日 星期四1. 阿里AI labs成立方言保护专项小组,投入1亿元保护汉语方言2. 小红书上线"品牌号",并进行五大模块升 ...

  8. 2021-03-13 大数据课程笔记 day52

    @R星校长 基于Flink的城市交通监控平台 1.1 项目整体介绍   近几年来,随着国内经济的快速发展,高速公路建设步伐不断加快,全国机动车辆.驾驶员数量迅速增长,交通管理工作日益繁重,压力与日俱增 ...

  9. 2021-01-27 大数据课程笔记 day7

    @R星校长 Nginx 问题引入 单个 tomcat 支持最高并发 怎么解决高并发问题,解决单个服务器过载问题? Nginx概述 Nginx 介绍 1. Nginx ("engine x&q ...

  10. 2021-03-19~20 大数据课程笔记 day58day59

    @R星校长 1 Scala 1.1 [重点]Scala六大特性  1) 与java无缝整合  2) 类型自动推断  3) 并发和分布式  4) Trait特质特性  5) Match模式匹配  6) ...

最新文章

  1. linux touch命令 新建文件 更新文件时间
  2. html元素做3d变换,CSS 3D变换
  3. 如何学好C、C++------思维方式的转变
  4. 2021全国大学生物联网大赛记
  5. PHP一个比较完善的树形结构代码
  6. 【渝粤教育】广东开放大学 劳动关系理论与实务 形成性考核 (1)
  7. Java 变量、数据类型
  8. 阿里P6Java工程师的学习经历自述,希望新人少走弯路
  9. 网页设计中常用的HTML代码
  10. 原理图端口符号_何为电气原理图和接线图?
  11. 原创科幻短篇《Bug》
  12. 查询oracle中所有的用户,如何查询Oracle中所有用户信息
  13. Easypanel linux离线安装,easypanel
  14. 关于用transmac黑苹果制作引导盘无法识别
  15. apple id两步验证服务器,apple id两步验证 苹果Apple ID两步式验证设置使用教程
  16. 如何解决Word只能用安全模式打开
  17. java阿里面试官直接告诉你录取答案,你还在犹豫那就晚了
  18. 毕业设计-基于MATLAB的含噪语音信号降噪处理系统
  19. 支付宝签名php,支付宝支付之php后台签名实现方法
  20. 基于多元线性回归算法的5G基站能耗模型

热门文章

  1. WinRAR 破解注册
  2. 职场险恶,程序员看完都惊呆了
  3. 菜鸟供应链实时数仓的架构演进及应用场景
  4. JAVA网络协同办公自动化
  5. MySQL技能树学习总结
  6. Neo4j 爬坑笔记for3.2.6
  7. 大一新生计算机掌握情况word,2021年大一计算机学习心得word版
  8. GAN (Generative Adversarial Nets 生成对抗网络)
  9. 搭建gos_快速浏览gOS –但不要称其为Google
  10. ROI Pooling和ROI Align、ROI Warp解析