模块:
百度云视频连接:
https://pan.baidu.com/s/1k0rfHfQRRbHDqIXqT4FLjg&shfl=sharepset
代码较少的时候,写在一个文件里体现不出什么缺点,但是随着代码量越来越多,代码的维护越来越难。为了解决难以维护的问题,我们把很多相似功能的函数分组,分别放到不同的文件中,这样每个文件包含的功能相对较少,且对于每个文件的大致功能可以用文件名来体现,很多编程语言都是这么组织代码结构的,对于python来说,一个.py就是一个模块,
优点:
1、提高代码的可维护性。
2、提高代码复用度,当一个模块完毕,可以被多个地方引用。
3、引用其他的模块(内置模块和三方模块以及自定义模块)。
4、避免函数名和变量名的冲突。
使用标准库中的模块:
import sys
print(sys.argv)
#获取命令行参数的列表
for i in sys.argv:
print(i)
name = sys.argv[1]
age = sys.argv[2]
hobby = sys.argv[3]
print(name,age,hobby)
#自动查找所需模块的路径的列表
print(sys.path)
打开黑明终端,输入python,空格,拉入写代码的.py,空格,输入内容,回车
使用自定义模块:
引入模块,可以一次性引入多个,例如:import time,random,os
1、引入自定义模块:格式:import 模块名
#整体引用
#注意:引入自定义模块,不用加.py后缀,一个模块只会被引入一次,不管执行多少次import。这是为了防止膜快被多次引入。
使用模块中的内容:格式:模块名.函数名/变量名
2、引入自定义模块:格式:from module(模块名) import name(函数名) [,name2][…name n]
#从模块中导入一个指定部分到当前命名空间。
此时,使用模块中的内容:格式:函数名/变量名#这时不用写模块名.。
这种方式导入的弊端是,程序内部的函数可以将模块中的同名函数覆盖。
3、引入自定义模块:格式:from module(模块名) import *
作用:把一个模块中所以内容全部倒入当前命名空间。
不建议过多使用
此时,使用模块中的内容:格式:函数名/变量名#这时不用写模块名.。
这种方式导入的弊端是,程序内部的函数可以将模块中的同名函数覆盖。
__name__属性:
模块就是一个可执行的.py文件,一个模块被另一个程序引入,不想让模块中的某些代码执行,可以使用__name__属性来使程序仅调用模块中的一部分。
每一个模块都有一个__name__属性,当其值等于__main__时,表明该模块自身在执行,否则被引入其他文件。
#当前文件如果为程序的入口文件,则__name__属性的值为__main__
if __name__ == '__main__':
包:
不同的人写的模块同名怎么办?为了解决模块名的冲突,引入了按目录来组织模块的方法,称为 包 。
特点:引入了包以后,只要顶层的包不与其他人发生冲突,那么模块都不与别人的发生冲突。
注意:目录只有包含一个“init.py”的文件,才被认为会是包。,主要是为了避免一些滥竽充数的名字,基本上目前这个文件中什么也不出写。
格式:import 包.模块名
使用:包.模块名.函数名()
第三方的模块:
windows系统:安装python是勾选了pip和Add python.exe to path
Mac和Linux系统:无需安装。
要安装第三方模块,需要知道模块的名字。
Pillow
是一个强大的处理图像的工具库。
通过黑明终端下载:
pip -V
pip install Pillow
windows如果安装失败,报错,输入pip install --upgrade pip
#引入第三方库
from PIL import Image
#打开图片
im = Image.open('捕获.jpg')
#查看图片的信息
print(im.format,im.size,im.mode)
#设置图片大小
im.thumbnail((150,100))
面向对象思想:
软件编程就是将我们的思维转变为计算机能够识别的语言的一个过程。
设计类:
类名:见名知意,首字母大写,其他遵循驼峰原则
属性:见名知意,其他遵循驼峰原则
行为(方法、功能):见名知意,其他遵循驼峰原则
创建类:
类是一种数据类型,本身并不占内存空间,根学过的number,string,boolean等类似。用类创建实例化对象(变量),对象占内存空间。
格式:
class 类名(父类列表):
属性
行为
#object:基类、超类,所有类的父类,一般没有合适的父类就写object
class Person(object):
#定义属性(定义变量)
name = ''
age = 0
height = 0
weight = 0
#定义方法(定义函数),方法的参数必须以self当地一个参数
#self代表类的实例(某个对象)
def run(self):
print('run')
def eat(self,food):
print('eat'+food)
使用类实例化对象:
格式:对象名 = 类名(参数列表)
#没有参数小括号也不能省。
例子:
per1 = Person()
print(per1)
print(type(per1))
print(id(per1))
per2 = Person()
print(per2)
print(type(per2))
print(id(per2))
结果:
<main.Person object at 0x00000000022A3710>
<class ‘main.Person’>
36321040
<main.Person object at 0x0000000001DEA2B0>
<class ‘main.Person’>
31367856
访问对象的属性与方法:
1、访问属性:
格式:对象名.属性名
赋值:对象名.属性名 = 新值
2、访问方法:
格式:对象名.方法名(参数列表)
#object:基类、超类,所有类的父类,一般没有合适的父类就写object
class Person(object):
#定义属性(定义变量)
name = ''
age = 0
height = 0
weight = 0
#定义方法(定义函数),方法的参数必须以self当地一个参数
#self代表类的实例(某个对象)
def run(self):
print('run')
def eat(self,food):
print('eat '+food)
def openDoor(self):
print('已经打开冰箱门')
def fillEle(self):
print('已经把大象装进冰箱了')
def cloceDoor(self):
print('已经关上冰箱门')
per = Person()
#访问属性
per.name = 'tom'
per.age = 18
print(per.name,per.age)
#访问方法
per.openDoor()
per.fillEle()
per.cloceDoor()
per.eat('apple')
结果为:
tom 18
已经打开冰箱门
已经把大象装进冰箱了
已经关上冰箱门
eat apple
#问题:目前看来Person创建的所有对象属性都是一样的。
对象的初始状态(构造函数):init()
在使用类创建对象的时候自动调用。
注意:如果不是显示的写出构造函数,默认会自动添加一个空的构造函数。
class Person(object):
#定义属性(定义变量)#有了__init__(),这里的定义属性就没有意义了,下面的__init__()那去定义
# name = ''
# age = 0
# height = 0
# weight = 0
#定义方法(定义函数),方法的参数必须以self当地一个参数
#self代表类的实例(某个对象)
def run(self):
print('run')
def eat(self,food):
print('eat '+food)
def __init__(self,name,age,height,weight):
#定义属性
self.name = name
self.age = age
self.height = height
self.weight = weight
print('@@@')
per = Person('lilei',20,12,34)
print(per.name,per.age)
per2 = Person('liuming',15,42,64)
print(per2.name,per2.age)
结果为:
lilei 20 12 34
@@@
lilei 20
liuming 15 42 64
@@@
liuming 15
self:
代表类的实例,而非类,哪个对象调用方法,那么该方法中的self就代表那个对象
self.__class__代表类名
class Person(object):
def run(self):
print('run')
def eat(self,food):
print('eat '+food)
def say(self):
print('hello,my name is %s,i am %d years old'%(self.name,self.age))
def __init__(self,name,age,height,weight):
self.name = name
self.age = age
self.height = height
self.weight = weight
per = Person('lilei',20,12,34)
print(per.name,per.age)
per.say()
per2 = Person('liuming',15,42,64)
print(per2.name,per2.age)
per2.say()
结果为:
lilei 20
hello,my name is lilei,i am 20 years old
liuming 15
hello,my name is liuming,i am 15 years old
注意:self不是关键字,换成其他的标识符也可以,但是一般都用self
class Person(object):
def run(self):
print('run')
print(self.__class__)
per = Person()
per.run()
结果为:
run
<class ‘main.Person’>
析构函数:
del()释放对象时自动调用
class Person(object):
def run(self):
print('run')
def eat(self,food):
print('eat '+food)
def __init__(self,name,age,height,weight):
self.name = name
self.age = age
self.height = height
self.weight = weight
def __del__(self):
print('这里是析构函数')
per = Person('lilei',20,12,34)
del per#释放对象,对象释放以后就不能在访问了
# while 1:
# pass
def func():
per2 = Person('aa',1,2,3)
func()
#这里没有手动释放,也没有因为程序结束而释放,
# 但是在函数里定义的对象,会在函数结束时释放,
# 这样可以用来减少内存的浪费。
while 1:
pass
结果为:
这里是析构函数
这里是析构函数
重写函数:
将函数重新定义写一遍
str():在调用print打印对象时自动调用,是给用户用的,是一个描述对象的方法。
repr():是给机器用的,在python解释器里直接敲对象名在回车后调用的方法。
注意:在没有str,且有repr时,str=repr
所以以后写str就可以实现了。
优点:当一个对象的属性值很多,并且都需要打印,重写了__str__()方法后,可以简化代码
class Person(object):
def run(self):
print('run')
def eat(self,food):
print('eat '+food)
def __init__(self,name,age,height,weight):
self.name = name
self.age = age
self.height = height
self.weight = weight
def __str__(self):
return '%s %d %d %d' % (self.name,self.age,self.height,self.weight)
per = Person('lilei',20,12,34)
print(per)
结果为:
lilei 20 12 34
访问限制:
如果想要让变量在外部不能直接被访问,只需在变量名前加__,那么这个属性就变成了私有属性。私有属性只能内部使用,外部不能使用。
per = Person('lilei',20,12,34)
print(per.age)
per.age = 30
print(per.age)
结果为:
20
30
class Person(object):
def __init__(self,name,age,height,weight,money):
self.name = name
self.age = age
self.height = height
self.weight = weight
self.__money = money
def set(self,money):
if money < 0:
money = 0
self.__money = money
def get(self):
return self.__money
per = Person('lilei',20,12,34,100)
per.set(10)
print(per.get())
私有属性一般会写set和get方法,用于变值。但不能直接访问__money,因为python解释器把__money变成了_Person__money,所以访问不到是因为找不到这个变量名,也就是说私有属性是以了_Person__money这个名字存的,用这个名字就可以外部访问了,但是不建议这么干。而且不同的编译器可能存在不同的解释变量名不一致。
注意:在python中,__XXX__属于特殊变量,可以直接访问的。
在python中,_XXX_的变量,外部也是可以直接访问的。但是按照约定的规则,我们看到这种变量时,当它当成私有的,不要直接访问。
实例:人开枪射击子弹
三个类:
人:
类名:Person
属性:gun
行为:fire
枪:
类名:Gun
属性:bulletBox
行为:shoot
弹夹:
类名:BulletBox
属性:bulletCount
行为:无
class BulletBox(object):
def __init__(self,count):
self.bulletCount = count
class Gun(object):
def __init__(self, bulletBox):
self.bulletBox = bulletBox
def shoot(self):
if self.bulletBox.bulletCount == 0:
print('没有子弹了')
else:
self.bulletBox.bulletCount -= 1
print('剩余子弹:%d发'%self.bulletBox.bulletCount)
class Person(object):
def __init__(self, gun):
self.gun = gun
def fire(self):
self.gun.shoot()
def fillBullet(self,count):
self.gun.bulletBox.bulletCount = count
bulletBox = BulletBox(5)
gun = Gun(bulletBox)
per = Person(gun)
per.fire()
per.fire()
per.fire()
per.fire()
per.fire()
per.fire()
per.fire()
per.fillBullet(2)
per.fire()
per.fire()
per.fire()
结果为:
剩余子弹:4发
剩余子弹:3发
剩余子弹:2发
剩余子弹:1发
剩余子弹:0发
没有子弹了
没有子弹了
剩余子弹:1发
剩余子弹:0发
没有子弹了