包和模块

在python种包与普通文件夹的区别是,在包内要创建一个_init_.py文件,来标识它不是一个普通文件夹,而是一个包。

一个项目可以包含多个包,一个包可以包含多个子包,也可以包含多个模块
例如:
avatar

模块

在python中一个以.py结尾的python文件就是一个模块,不同包下可以有相同名称的模块,模块之间使用”包名.模块名”的方式区分。如果一个模块中引入其他模块有多种方式可以实现

描述 引入方法
引入单个模块 import model_name
引入多个模块 import model_name1,model_name2
引入模块中的指定函数或类 from model_name import func…

例如:

1
2
3
4
5
6
/buss/model1.py
def project_info():
print("*"*20)#打印20个*号
print(""*4,"python项目",""*4)

import buss.model1.py

_init_.py模块

在python中一个包中必须包含一个含默认的_init_.py模块。在pycharm中会自动创建一个。

1
2
3
4
5
6
7

## \_name_变量
和C,JAVA等编写的程序,在运行时都是需要从一个主入口开始执行的。以面向对象的JAVA为例,在编写JAVA程序时,要在代码的主类中定义一个main函数作为程序的入口,编译器在执行时先找到main函数,从main函数开始运行

python属于<font color="#0000dd">脚本语言</font>,在运行时与其他编程语言不同,python程序没有编译过程,不需要进行编译成二进制代码再运行,而是从上到下依次执行的

在python中内部定义了一个```_name_```变量,当被直接运行输出时,可以当作是```_main_
1
2
3
4
5
def info():
print("当前运行的_name_值是{}".format(_name_))

结果为:
当前运行的_name_值是_main_

当引入了test_model模块时,并调用test_info函数

1
2
3
4
5
6
7
8
9
10
11
import test_model
def info():
print("当前运行的_name_值是{}".format(_name_))
print("---------------------")
info()
test_model.test_info()

结果为:
当前运行的_name_值是_main_
---------------------
test_info正在运行,_name_值是test_model

通过这个例子可以看出当有模块被引入,且调用了其中的函数或方法是,_name_的值等于模块名

所以在通常情况下,如果一个python源码文件既要作为模块在其他地方被引用,又要在其他地方单独运行时,就可以在源码文件中国加入if_name_=="_main_"的条件判断,也可以将这段代码作为Python源码文件的入口

面向对象

概念

简单的来说,面向对象编程就是一种解决软件复用的设计和编程方法。
对象就是类的实例化

类与对象

类是虚的,抽象的
对象是实的,就是类的实例化或被称为是具体表现

类由类名,属性,方法三部分组成

1
2
3
class 类名:
def 方法名(self[,参数列表]):
方法体

定义类时要先使用class关键字,声明这是一个类,类名要遵循标识符的规则。
类内部定义的函数叫做方法,当调用一个对象的方法时,对象会将自身的引用传递到调用的方法中。

对象

创建对象的方法是:变量=类名([参数列表])
例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Dog:
def eat(self):
print("吃骨头")
def drink(self):
print("喝水")
def run(self):
print("跑")
wangcai=Dog()
wangcai.eat()
wangcai.drink()
wangcai.run()

结果为:
吃骨头
喝水

_init_构造方法

构造方式的作用是在创建一个类的对象时,进行一些初始化操作。
例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Dog:
def _init_(self):
print("正在初始化")
def eat(self):
print("吃骨头")
def drink(self):
print("喝水")
def run(self):
print("跑")
wangcai=Dog()
wangcai.eat()
wangcai.drink()
wangcai.run()

结果为:
吃骨头
喝水


结果显示我们并没有调用_init_构造方法,程序自动调用了该构造方法,打印了其中的内容
我们可以利用构造函数来对参数赋值:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Dog:
def _init_(self,variety,gender):
print("正在初始化")
self.variety=variety
self.gender=gender
print("初始化结束")
#创建对象
wangcai=Dog("金毛""雄性")
print("旺财的品种是{}".format(wangcai.variety))
print("旺财的性别是{}".format(wangcai.gender))

结果为:
正在初始化
初始化结束
旺财的品种是金毛
旺财的性别是雄性

从结果我们可以看出,_init_构造函数在对象实例化时执行。

访问权限

JAVA中的访问权限有default,public,private,protected。分别是默认的,公共的,私有的和保护的

在python中不需要任何关键字修饰,只需要在属性或方法名前添加两个下划线__即为私有的访问权限,反之则是公有的
例如:

1
2
3
4
class Dog:
def _init_(self,name):
self.name=name
self.__age=1#私有属性

继承

继承是面向对象带来的好处之一,解决了代码重用的问题

单继承

所谓的单继承就是只继承一个父类
定义格式:class Son(Father)

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Animal:
def eat(self):
print("吃")
def drink(self):
print("喝")
def sleep(self):
print("睡")

class Dog(Animal):#继承了Animal类
def hand(self):
print("握手")

wangcai=Dog()
wangcai.eat()
wangcai.drink()
wangcai.hand()
wangcai.sleep()

结果为:


握手


从结果可以看出Dog类中并没有定义eat,drink,sleep方法,但是由于继承了父类Animal,所以就继承了其中的所有公有方法和属性

super函数

如果在子类中想要调用父类的方法,有两种实现方法:
第一种:父类名.方法名(self[参数列表])
第二种:super().方法名

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Dog(Animal):
def hand(self):
print("握手")

class goldenDog(Dog):
def guide(self):
print("我能导航")
print("导航前请与我握手")
Dog.hand(self)

duoduo=goldenDog()
duoduo.guide()

结果为:
我能导航
导航前请与我握手
握手

或者

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Dog(Animal):
def hand(self):
print("握手")

class goldenDog(Dog):
def guide(self):
print("我能导航")
print("导航前请与我握手")
super().hand()

duoduo=goldenDog()
duoduo.guide()

结果为:
我能导航
导航前请与我握手
握手

看到结果是一样的,在简单的继承下两者并无什么区别,但是在复杂的继承条件下,super()函数表现的更为灵活简单

重写

重写就是在子类中定义与父类同名的方法,而其中实现的内容却不一样
例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class Animal:
def eat(self):
print("吃")
def drink(self):
print("喝")
def run(self):
print("跑")

class Dog(Animal):#继承了Animal类
def run(self):
print("狗能摇着尾巴跑")

class Cat(Animal):#继承了Animal类
def run(self):
print("猫不能摇着尾巴跑")

animal=Animal()
animal.run()

dog=Dog()
dog.run()

cat=Cat()
cat.run()

结果为

狗能摇着尾巴跑
猫不能摇着尾巴跑

多继承

多继承其实就是一个子类继承了两个或两个以上的父类
定义格式:class Son(Father1,Father2...)

其余方法和定义与单继承基本一致,不多介绍

异常处理

在程序运行过程中常会遇到各种异常,代码问题,网络问题,逻辑问题等,需要对这些异常进行预处理,才能保证程序的正常执行

捕获异常

格式:

1
2
3
4
try:
可能产生异常的代码块
except ExceptionType as err:
异常处理

例如:
打开一个不存在的文件,产生异常

1
2
3
4
5
6
7
file=open("test.txt")
print(file.read())
file.close()
print("读取结束")

结果为
运行就会造成异常

捕获异常:

1
2
3
4
5
6
7
8
9
10
try:
file=open("test.txt")
print(file.read())
file.close()
except FileNotFoundError as err:
print("读取结束,文件不存在",err)


结果为
读取结束,文件不存在

捕获多个异常

格式:

1
2
3
4
try:
可能产生异常的代码块
except (ExceptionType1,ExceptionType2,...) as err:
异常处理

其余与捕获异常基本类似

捕获全部异常

格式:

1
2
3
4
try:
可能产生异常的代码块
except Exception as err_all:
异常处理

异常中的finally语句

在程序中,如果一段代码必须要执行,就是无论发生异常,都要执行的代码,需要用finally语句
例如:

1
2
3
4
5
6
7
8
9
10
11
try:
f=open("test.txt")
print("打印文件内容")
except Exception as err_all:
print("捕获到了异常",err_all)
finally:
print("关闭连接")

结果为:
捕获到了异常
关闭连接

raise抛出异常

如果我们想在自己写代码的过程中遇到问题也抛出异常,可以使用raise语句
例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def div(a,b):
if b==0:
raise ZeroDivisionError
else:
return a/b

div(2,0)

结果为:
Traceback (most recent call last):
File "D:/TIM_DOWLOAD/233.py", line 7, in <module>
div(2, 0)
File "D:/TIM_DOWLOAD/233.py", line 3, in div
raise ZeroDivisionError
ZeroDivisionError

Process finished with exit code 1

文件操作

在日常开发中,我们需要将数据写入某个文件,或者将文件中的数据读取到,就需要使用文件操作

读写文件

打开文件

python中打开文件使用内置函数open打开该文件
例如:

1
2
3
f=open("test.txt","r")

r的意思是只读,即read的缩写

1
2
f=open("test.txt","w")
w的意思是可编辑,即write的缩写

写文件

python中写文件的方法有write()writelines()

1.write():
使用该方法可以将字符串数据写入到文件中.
例如:

1
2
3
4
f=open("stunames.txt","w")
f.write("Tome")
f.write("David")
f.write("Carl")

2.writelines():
使用该方法只能将一个字符串写入到文件中
例如:

1
2
f=open("stunames.txt","w",encoding="utf-8")
f.writelines(["张三\n","李四\n","王五\n"])

3.close()
在使用完写文件操作后,需要使用close()方法将其关闭,避免占用空间导致资源浪费

1
2
3
f=open("stunames.txt","w",encoding="utf-8")
f.writelines(["张三\n","李四\n","王五\n"])
f.close()#关闭写操作

读文件

python中的读文件方法有read()readlines()

1.read():

1
2
3
4
5
6
7
8
with open("stunames.txt","w",encoding="utf-8") as f:
data=f.read()
print(data)

结果:
张三
李四
王五

2.readlines()
该方法可以将整个文件中的内容一次全读取出来,返回一个列表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
with open("stunames.txt","w",encoding="utf-8") as f:
data=f.readlines()
print(data)

for i in range(0,len(lines)):
print("第{}行:{}".format(i,lines[i]))

结果为:
['张三\n','李四\n','王五\n']
0行:张三

1行:李四

2行:王五

文件管理

除了打开,读和写文件,还要有删除,重命名,创建文件夹等功能

1.rename(oldfile,newfile)函数
字面意思,就是重命名文件
例如:

1
2
import os
os.rename("test.txt","测试.txt")

2.remove(path)函数
删除指定文件
1
2
import os
os.remove("测试.txt")

3.mkdir(path)函数
创建文件夹

1
2
import os
os.mkdir("d://testdir")

4.getcwd函数
获取程序的绝对路径

1
2
import os
print(os.getcwd())

5.listdir(path)函数
获取指定路径下的文件列表

1
2
3
import os
lsdir=os.listdir("./")
print(lsidr)

6.rmdir(path)函数
删除指定路径下的空文件夹
1
2
import os
os.rmdir("./datas")

总结

1.可以在文件头加上if_name_=="_main_":来保证该模块的运行,不被其他模块调用

2.单继承时,子类只能继承父类的非私有成员变量和非私有成员函数

3.由于在开发过程中,无法完全确定会出现的异常,所以建议采用except Exception as err_all的方式

4.在使用raise抛出异常时,无需写明异常类型,只需要写Exception即可

5.在文件操作时,读文件操作时,如果是只读操作读取不存在的文件,则会报错,如果是只写操作读取不存在的文件,则会自动创建一个文件