2021-02-15 大数据课程笔记 day26

时间煮雨
@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 = name
        self.color = color
    def run(self):
        print("%s--在跑"%self.name)
# 定义一个子类,继承Cat类,如下:
class Bosi(Cat):
    def setNewName(self, newName):
        self.name = newName
    def 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 = name
        self.color = color
    def __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来进行修饰  
	@classmethod
	def getCountry(cls):
		return cls.country 
p = People() 
print(p.getCountry()) #可以用过实例对象引用
print(People.getCountry()) #可以通过类对象引用

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

classPeople(object): 
	country = 'china'#类方法,用classmethod来进行修饰 
	@classmethod
	def getCountry(cls):
		return cls.country 
	@classmethod
	def 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):
    #根据用户指定的类型创建对应类的对象
    @staticmethod
    def 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 = 100
	print 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 = length
        self.atleast = atleast
    def __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:如果这行代码出现了异常,那么后面的代码不会运行
    pass2
    pass3
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 np

array= 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])
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值