Python基础学习

本次Python学习所有操作均以Mac环境为主。

一、安装Python

目前,Python有两个版本,一个是2.x版,一个是3.x版,这两个版本是不兼容的。由于3.x版越来越普及,这里将以最新的Python 3.x版本为基础。

如果Mac系统是OS X>=10.9,那么系统自带的Python版本是2.7。要安装最新的Python 3.x版本,可以通过Homebrew安装,执行以下命令:

brew install python3

在命令行输入 python , 进入到Python交互模式, 输入 exit() 可退出交互模式

此时会发现使用的python还是2.7版本,并没有被覆盖,可以参考https://www.jb51.net/article/116470.htm 进行配置,配置完成后输入python3 

 

python帮助文档:

https://docs.python.org/3.6/tutorial/index.html

https://docs.python.org/3.6/index.html

中文帮助文档

https://yiyibooks.cn/ 

 

二、变量

如何声明一个变量,直接 变量名 = 值

test = 123
print(test)

其他声明方式:

# 连续赋值声明 
a = b = c = d = 123
print(c)

# 多个变量多个值,使用 , 隔开
a,b,c = 1,2,3
print(a)

 

 变量的三要素:变量名、变量值、 变量的类型。

 变量在使用前都必须先赋值,然后才能使用。

在Python中,变量名必须以字母或下划线字符开头,可以包含字母、数字和下划线。大写字母和小写字母都是允许的。

使用 del 方法,可以删除某个声明过的变量,如需删除多个变量,可用 , 分隔

t = 'asdasd'
del t
print(t)  # 报错 t是未声明变量

 变量的作用域:

python变量的作用域一共分为四种:局部作用域(Local)     闭包函数外的函数中(Enclosing)    全局作用域(Global)   内建作用域(Built-in)

在函数体内定义的变量,在外部无法访问。 要在一个函数体内改变某个全局变量,需要使用 global 声明

定义在if 语句、for循环 和 while循环 中的变量,并且这些变量不是定义在函数体内的,变量默认为全局变量

 

三、运算符

Python运算符包括算术运算符、关系运算符、逻辑运算符、赋值运算符

算术运算符: +(加)  -(减)  *(乘)   /(除)    %(取余)  //(向下取整)    ** (次方)

x = 5
y = 3
a = 4
b = 2
print(x + y) #结果为 7
print(x - y)  #结果为2
print(x * y) #结果为15
print(x / y)  #结果为1.6666666666666667 不同的机器浮点数的结果可能不同
print(x // y) #向下去整结果为1
print(x % y) #两数相除取余结果为2
print(x**y) #5的3次幂结果为125
print(a / b) #结果为浮点数2.0
print(a % b)#取余结果为0
print(a // b)#取整结果为2

 

关系运算符: ==(等于) != (不等于)   > (大于)   < (小于)   >=(大于等于)<= (小于等于) 

a = 4
b = 2
c = 2
print(a == b) #False
print(a != b)  #True
print(a > b)   #True
print(a < b)   #False
print(a >= b) #True
print(c <= b) #True

 

逻辑运算符:and (并且)   or (或者)    not (非)

a = 4
b = 2
c = 0
print(a>b and b>c) #a>b为True继续计算b>c,b>c也为True则结果为True
print(a>b and b<c)#a>b为True继续计算c<b,b>c结果为False则结果为False
print(a>b or c<b) #a>b为True则不继续计算c<b,结果为True
print(not c<b) #c<b为True not True结果为False
print(not a<b) #a<b为False not Flase结果为True

 

 

 

 

三、数据类型

Python3 中有六个标准的数据类型:Number(数字)   String(字符串) List (列表)   Tuple (元组)   Set (集合)   Dictionary (字典) 

我们可以使用内置的 type() 函数来查询变量的数据类型

 

Numberl类型包含  int (整数类型)   float (浮点数)   bool (布尔类)  complex (复数)

bool (布尔类) 是int 的子类,也就是继承了int类型,所以它可以跟进行运算,会默认转为 1 或者 0

print(True + 1)   #  输出 2
print(True + 0.1)   #  输出 1.1
print(False + 1)   #  输出 1

 

complexf 复数 , 复数 具有实部和虚部两个部分,虚数 是 -1 的平方根的倍数,复数的虚部被表示为 j   ,如 c=3.0+1.2j    则c为复数

c = 3 + 1j
print(c)    #(3+1j)
print(c.real)    #输出c的实部 3.0
print(c.imag)    #输出c的虚部 1.0

 在Python 3里,只有一种整数类型 int,表示为长整型,没有 python2 中的 Long。

 

 String类型 用单引号或者双引号括起来

字符串的拼接使用 +   ;字符串的拼接必须两个都是字符串;可使用str() 进行类型转换

a = 'hello'
b = 'world'
c = 123
print(a + b + str(c))  # helloworld123

 

 重复输出同一个字符,使用 *n ,  n表示重复的次数;  例如重复输出3次  str*3

 字符串的截取使用  变量[头下标 : 尾下标]   如果尾下标是负数,表示从末尾的开始位置,比如-1 为倒数第1个字符结束。如果尾下标不写,默认截取到最后一位

a = 'hello'
b = 'world'
print(a[0])  # h
print(a[0:3]) # hel

 

 Python 使用反斜杠(\)转义特殊字符,如果你不想让反斜杠发生转义,可以在字符串前面添加一个 r,表示原始字符串:

print(r'hello \n world')  # hello \n world

 

 Python 字符串输出可以使用连续三个单引号、连续三个双引号 、  \符续行, 也就是完全输出书写的格式(空格全部保留) 

print(""" 我是一个程序员
  我刚开始学习python""")
print('''这是一个
         断句''') 
print('这是一个 \
         断句') 

strip() 方法 : 去掉字符串首尾指定的字符

find()  方法: 返回查找字符串中指定字符的下标

rfind()  方法: 从右边开始查找,返回查找字符串中指定字符的下标

replace() 方法:  字符串替换 

str1 = ' 两边有空格 '
print(str1.strip())
str1 = '123456789'
print(str1.find('5'))   # 4

 

 

 List 列表类型 有序排列的一组数据集合,可用下标索取,如  [1,2,3,4,5,6]

 和字符串一样,列表可以连接、重复和被索引和截取,列表的下标是从0 开始的

列表的拼接使用 + 号

a = [1,2,3]
b = [4,5,6]
print(a + b) # [1, 2, 3, 4, 5, 6]

 

重复输出一个列表,使用 变量名*n , n表示输出的次数

a = [1,2,3]
print(a * 3) # [1, 2, 3, 1, 2, 3, 1, 2, 3]

 

列表的截取使用  变量[头下标 尾下标]  含头不含尾   如果尾下标是负数,表示截取倒数第n个。

a = [0,1,2,3,4,5,6]
print(a[0:-5]) # [0, 1]
print(a[2:3])  # [2]

 

关于list的方法:

list.append() :  把一个元素添加到列表的尾部

list.extend() :  把一个列表合并到另一个列表中

list.insert(i , v) : 在列表指定位置插入某个元素,i 表示下标位置

list.remove(x) :  删除列表中值为 x 的第一个元素,不删除后面重复的值,如果没有该元素,返回一个错误

list.pop(i)删除列表指定位置的某个元素,如果没有传入下标索引,那么默认删除最后一个元素

list.clear()  : 清除某个列表所有的值,变为空列表,相当于 del a[:]

list.index(x) :  返回列表中第一个值为 x 的元素的下标值,如果没有匹配的元素则返回一个错误

list.count(x) : 返回x 在列表中出现的次数

list.sort()  :  将一个列表进行正序排序, 列表内的元素必须是统一类型

list.reverse() :  将一个列表进行倒序, 列表内的元素必须是统一类型

list.copy() :  返回一个列表的浅复制,等于 a[:]

 

将一个列表转换为队列   deque 模块

from collections import deque   # 从 collections 包引入 deque 模块

list1 = [1,2,3,4,5]
newList = deque(list1)
print(newList)   # deque([1, 2, 3, 4, 5])

newList.append(6)
print(newList)

newList.pop()
print(newList)

 

 

列表的推导式:

list1 = [2,3,4,5]
list2 = [34,56,78,90]
list3 = ['', '', '', '', '']

# 获得一个列表为list1 每个元素的平方
print([x**2 for x in list1])  #  [4, 9, 16, 25]

# 获得一个列表为list1 每个小于4的元素的平方
print([x**2 for x in list1 if x < 4])  # [4, 9]

# 获得一个列表为list1 每个元素的平方,并每个元素独立为一个列表  即二维列表
print([[x**2] for x in list1])   # [[4], [9], [16], [25]]

# 获得一个列表为 list1每一项分别与list2每一项相加的值 
print([x+y for x in list1 for y in list2]) # [36, 58, 80, 92, 37, 59, 81, 93, 38, 60, 82, 94, 39, 61, 83, 95]

# 去掉列表每一项的空格
print([x.strip() for x in list3])   #['这', '是', '带', '空', '格']

 

 

 

 

 Set 集合类型  是一组无序并且不重复的数据,作为一个无序的集合,set不记录元素位置或者插入点。 不存在下标, 如 {1, 2, 3, 4, 5}

如何创建一个集合,可以直接 变量名 = {值,值,... } ,   或者使用 set() 方法 ; 

一个合集被创建后,会自动去重

 

一个集合的内部数据位置是随机的, 同个集合每次调用时内部数据的位置都会改变 

  创建一个空的集合,必须使用 set() 方法 , 因为 变量名 = {}  表示的是一个空的字典

a = {11, 2, 3, 4}
b = set("abcdef")   # {'e', 'd', 'a', 'c', 'b', 'f'}

 

可以使用 in 或者 not in 来判断集合中是否存在某个元素 ,返回布尔值

a = {11, 2, 3, 4}
b = set("abcdef") 
print(2 in b)   # False
print(7 not in a)  # True

 

集合的运算有 差集(-)、并集(|)、交集(&)、对称差集 (^)

差集: a - b   结果等于 如果a合集中某个元素也存在于b合集中,则删除重复的元素, 即把a合集去掉 与b合集重复的元素; 等价于 difference() 方法

a = {1,2, 3, 4}
b = {3, 4, 5, 6}
print(a - b) # {1, 2}
print(b.difference(a)) # {5, 6}

 

并集 : a | b   结果等于a合集与b合集进行合并; 等价于 union() 方法

a = {1,2, 3, 4}
b = {3, 4, 5, 6}
print(a | b) # {1, 2, 3, 4, 5, 6}

 

交集: a & b  结果等于获得同时存在于a合集与b合集的元素;等价于 intersection() 方法

a = {1,2, 3, 4}
b = {3, 4, 5, 6}
print(a & b) # {3, 4}

 

对称差集: a ^ b  结果等于a合集与b合集进行合并,并去掉双方都存在的值;等价于 symmetric_difference() 方法

a = {1,2, 3, 4}
b = {3, 4, 5, 6}
print(a ^ b) # {1, 2, 5, 6}

 

关于集合的内置函数:

add() 方法: 往set集合中添加一个元素, 注意添加的元素不能为列表或者集合

a = {1,2, 3}
a.add("[123]")
print(a) # {1, 2, 3, '[123]'}

 

update() 方法: 往set集合中添加多个元素  添加的元素为列表或者集合,不能只添加一个元素

a = {1,2,3}
a.update(["564", 'a'])
print(a)  # {1, 2, 3, 'a', '564'}

 

clear() 方法: 清空一个集合所有元素

a = {1,2,3}
a.clear()
print(a)  # set()

 

copy() 方法: 复制一个集合

a = set('as132456')
b = a.copy()
print(b)  # {'s', 'a', '4', '5', '2', '6', '1', '3'}

 

remove() 方法: 删除集合中某个指定元素,若删除目标不存在,则会报错

discard() 方法: 删除集合中某个指定元素,不存在也不会报错

a = set('123')
a.remove('1')
print(a)  # {'2', '3'}

 

pop() 方法: 获得当前集合中的第一个元素

a={1,2,3,4,5,6}
print(a.pop())  # 1

 

len() 方法: 返回当前集合中的元素个数, 也可写成  a.__len__()

a={1,2,3,4,5,6}
print(a.__len__())  # 6
print(len(a))    # 6

 

frozenset()方法: 返回一个冻结的集合,所谓的冻结就是这个集合不能添加或者删除任何元素。该方法的参数必须是一个可迭代的对象,比如列表、集合、元组、字典等

a={1,2,3,4,5,6}
frozenset(a)
print(frozenset(a))   # frozenset({1, 2, 3, 4, 5, 6})

 

 Tuple 元组类型   跟列表类型类似,不同之处在于元组的元素不能进行修改;用()表示。如 a = (1,2,23,4,('a','b'))

创建一个空的元组,使用 变量名 = () ;   当元组只有一个元素时,需要保留 , 号作为元组的类型区分,如 a = (1 , )

元组中的元素类型可以不同,元素的值也可以是另一个元组,实现元组的嵌套。

访问元组内的元素,使用 元组名[下标值] 

元组的截取 使用  元组名[头下标 :尾下标]

元组中的元素值是不允许改变的,不过我们可以对一个元组进行拼接   元组a + 元组b

元组的内置函数:

1、len(tuple):计算元组元素个数。


2、max(tuple):返回元组中元素最大值。
要求元组内的元素是同个类型

3、min(tuple):返回元组中元素最小值。 要求元组内的元素是同个类型


4、tuple(seq):将列表转换为元组。

a = (1,2,23,4,('a','b'))
print(len(a))   # 5
print(a[1:-1])  # (2, 23, 4)

 

dict 字典类型   如  dict1 = {'name': '小明', 'ega': 14}

字典是另一种可变容器模型,且可存储任意类型对象,键必须是唯一的,但值则不必,值可以取任何数据类型,但键必须是不可变的,如字符串,数字或元组。 

访问一个字典内部的值,使用  value = 字典名[key] 

往字典里面添加一个新的值或者改变一个值, 使用   字典名[key] = value

删除一个字典中某对键值,有三种方法:del 字典名[key]      字典名.pop(key)       字典名.popitem()

dict1 = {'name': '小明', 'ega': 14}
del dict1['ega']
print(dict1)   # {'name': '小明'}
dict1 = {'name': '小明', 'ega': 14}
dict1.pop('ega')
print(dict1)   # {'name': '小明'}
dict1 = {'name': '小明', 'ega': 14}
dict1.popitem()    # 随机返回并删除字典中的一对键和值(一般删除末尾对)。
print(dict1)   # {'name': '小明'}

 

 关于dict字典的方法:

字典名.pop(key) : 删除字典对应的某对键值

字典名.popitem(): 随机返回并删除字典中的一对键和值(一般删除末尾对)

字典名.clear() :     清空一个字典

字典名.update(字典名): 合并两个字典

字典名.keys() :  获得一个字典所有的键值,返回list 格式

字典名.values() : 获得一个字典所有的值,返回list格式

len(字典名):   获得一个字典的键值个数

str(字典名):   将一个字典转为字符串

dict2 = dict1.copy() :   复制一个字典

key in 字典名:如果键在字典dict里返回true,否则返回false

 

可更改(mutable)与不可更改(immutable)对象 :

在python中,strings 、tuples、numbers 是不可更改的对象; 而 list 、dict 等则是可以修改的对象

python中的可哈希和不可改变性: 

通过help() 方法,包含 __hash__(self, /) 方法的为可哈希对象;

python中所有不可更改的对象都为可哈希对象,如string、tuple、frozenset()

 

四、条件控制语句 

if 判断     if -- elif -- else

python 的 if 判断语句不存在()以及 { } 符号,主要以缩进符的不同区分代码块

#encoding=utf-8

score = input('请输入分数:')
if int(score) >= 90:
  print('优秀')
elif int(score) < 90 and int(score) >= 80:
  print('良好')
else:
  print('一般')

 

while 循环语句    while -- else    当循环条件不成立的时候执行else

test = 1
while(test < 100):
  print('循环输出'+ str(test))
  test += 1
else:
  print('循环结束')

  

 for 循环语句    for key in arrar--else   else 语句只在for循环正常退出时执行,被强制退出的情况下不执行; 主要用于遍历,除了Number类型,几乎都够使用变量;

list1 = ['小明','小洁','小梦']
for vaule in list1:
  print(vaule)    # 依次输出 小明  小洁  小梦
else:
  print('循环正常结束')

dict1 = {'name':'小明','ega':18, 'height': 100}
for key in dict1:
  print(key)  # 依次输出  name  ega  height

for value in dict1.values():
  print(value)  # 依次输出  小明  18  100

 

enumerate() 方法:  循环的同时获得下标值

list1 = ['小明','小洁','小梦']
for key, vaule in enumerate(list1):
  print(key, vaule)    # 依次输出 0 小明  1 小洁  2 小梦
else:
  print('循环正常结束')

  
dict1 = {'name':'小明','ega':18, 'height': 100}
for key, value in enumerate(dict1):
  print(key, value)  # 依次输出 0 name  1 ega  2 height

 

 range(a, b, c) 方法: 返回一个数字范围的队列,可传三个参数: a表示序列开始的值,b表示序列结束的值(结束值不包含b), c表示迭代的值(c的值也可以是负数)。 当只传一个参数的时候,a默认为0,c默认为1

for t in range(10):
  print(t)    #  依次输出 0 ~ 9

for n in range(2,10, 1):
  print(n)    #  依次输出 2 ~ 9

for i in range(5,1, -1):
  print(i)    #  依次输出 5 ~ 2

 

zip() 方法:  配合for 循环使用可同时遍历多个列表

list1 = [2,3,4,5]
list2 = [34,56,78,90]

for a,b in zip(list1, list2):
  print(a, b)   
  # 2 34
  # 3 56
  # 4 78
  # 5 90

 

 

五、函数  使用 def 创建

pythons使用def 创建一个函数,使用缩进符区分代码块,不存在 {} , 一定要加上 ()

使用return 返回函数内某个值,默认返回None

def test():
  print('这是函数逻辑')

test()

 关于传参:

声明函数时可设置默认参数,默认参数必须写在后面

调用函数并进行传参时,如果使用关键字传参时,可以不按照参数顺序,关键字必须跟形参一致

不定长参数 ,格式为 *变量名, 表示不确定几个参数,它是一个Tuple元组类型 。 在函数内部可以按照传入的顺序进行遍历使用;

def test(name, ega, height = 185):
  print(str(ega) + '岁的'+ name + '今年身高' + str(height) )

test('小米', 18, 180)  # 18岁的小米今年身高180

test(ega = 12, height= 160, name='小洁')  #12岁的小洁今年身高160

 

def test(*v):
  print(v)   # ('小洁', 18, 175)
  
test('小洁', 18, 175)

 

匿名函数  lambda    用表达式的方式表示一个函数   书写格式为    函数名 = lambda 参数:执行逻辑 ,   如果执行的逻辑是计算,会默认 return 计算结果

所谓匿名函数,指的是不再使用 def 语句来定义一个函数

lambda声明的函数传参方式跟 def 定义的函数一致;

test = lambda : print('这是执行逻辑')

test2 = lambda value: print(value)

test3 = lambda a,b,c: a + b + c   

test()

test2('这是执行逻辑')

print(test3(1,2,3))  # 6  默认return

 

关于函数中的变量:

在函数内部声明的变量,为局部变量,函数外部无法调用。

当函数内的局部变量和全局变量同名时,会默认访问局部变量

函数内部可以调用全局变量,当需要改变全局变量的值时,需要用 global 声明该变量为全局变量

sum = 100
def test():
  global sum
  sum = sum + 1
  print(sum)

test()   # 101

 一个函数return出另一个函数,称为闭包;在函数闭包中,当需要改变外层函数变量的值时,需要使用 nonlocal 声明该变量为外层函数变量

def test():
  num = 1

  def out():
    nonlocal num
    num = num + 1
    return num

  return out

print(test()())   # 2

 

 

函数的参数传递:

不可变类型:如整数、字符串、元组等作为参数传递时,例如fun(a) ,传递的只是a的值,没有影响a 对象本身。如果在 fun(a) 内部修改 a 的值,只是修改另一个复制的对象,不会影响 a 本身的值

可变类型:   如列表、字典作为参数传递时,例如 fun(list) ,  则是将 list 真正传过去, 在fun(list) 内部修改 list 的值, 外部的 list 也会跟着改变。

 

六、Python的输入和输出

input() 方法: 表示从键盘接收用户输入的一段文本

str1 = input()
print(str1)

python 的输入除了转换为字符串进行拼接外,还支持特定字符替换: 

%s  表示一个字符串,  支持保留空格, 格式为 %位数s ,默认为左边空格,如果位数是负数,那么默认为右侧空格;

%d  表示一个数字,  支持保留空格, 格式为 %位数d ;  ,默认为左边空格,如果位数是负数,那么默认为右侧空格;

%f   表示一个浮点数    支持四舍五入,写法为  %.位数f   ;  如保留两位小数位 %2.f 

name = '小米'
age = 18.8
print('我的名字叫%4s,我今年%-8d岁'%(name,age))  # 我的名字叫  小米,我今年18      岁

format()  方法:  在python的输入中进行字符替换,推荐写法: 

保留n位小数,使用 : . nf   ;   

保留n个空格,使用 : n  ;  分别使用 >   <   ^   表示左对齐、右对齐、居中

 

name = '小米'
age = 18.888
print('我的名字叫{0:^8},我今年{1:8}岁'.format(name,age))     # 我的名字叫   小米   ,我今年  18.888岁
print('我的名字叫{name},我今年{age:.2f}岁'.format(name=name,age=age))    # 我的名字叫小米,我今年18.89岁

 

输出格式的转换:

八进制 :  :o       十进制 :  :d

二进制 :  :b       十六进制 :  :x     按3位数分隔 :  :,

test = 1234657898
print('这是八进制:{:o}'.format(test))    # 这是八进制:15
print('这是八进制:{:b}'.format(test))    # 这是二进制:1101
print(' 按3位分隔:{:,}'.format(test))    # 按3位分隔:1,234,657,898

 

srt() 方法 和   repr() 方法的区别:

 str()  转换输出的字符是给用户看的 ,  遇到/n 的时候会进行转译

repr()  转换输出的字符是给解释器看的, 照常输出,不支持转译

 

 

七、关于模块

系统模块:
使用import方法导入python的内置模块,导入多个模块可用 逗号 分隔

单独导入某个模块内的某个方法, 格式为  from 模块 import 方法名

查看某个模块下所有的方法,使用 dir()  方法

import math
from math import sqrt

print(dir(math))

 

常用的系统模块:

sys 模块:

sys.argv :    返回的是一个元组,下标0 表示的是当前的文件名,后面依次为用户键盘输入的值。
sys.path :   返回的是一个元组,为python 的搜索模块的路径集
sys.stdout.write :   输出,等同于 print() 方法
sys.stdin.read  :   用户输入,等同于  input()  方法
import sys

print(sys.argv)
print(sys.path)

 os 模块/ math 模块

math.ceil(a)  : 求出不小于a的最小整数

math.floor(a) : 求出不大于a的最大整数

import math

print(math.ceil(12.34))   # 13
print(math.floor(12.34))  # 12

 

random 模块:
random.choice(list):  从合集中随机获得一个数值
random.sample(list, n) :   随机从集合中获得n个数值,返回list
random.random() :   随机产生一个0 ~ 1 的数
import random

print(random.sample(range(100), 10))   # 随机获得1~99中10个数字组成的列表,不重复
print(random.random())

 

自定义模块:

可以使用 def 声明一个函数并 return 某个值 作为自定义模块

自定义模块放在当前工作目录下,或者安装python的根目录下,可以使用 import 直接引用 ,使用 sys.path   打印输出的路径都可以放

 

import sys

print(sys.path)
#['/Users/zhengweijie/Desktop/pythonTest', '/usr/local/Cellar/python3/3.6.3/Frameworks/Python.framework/Versions/3.6/lib/python36.zip', '/usr/local/Cellar/python3/3.6.3/Frameworks/Python.framework/Versions/3.6/lib/python3.6', '/usr/local/Cellar/python3/3.6.3/Frameworks/Python.framework/Versions/3.6/lib/python3.6/lib-dynload', '/Users/zhengweijie/Library/Python/3.6/lib/python/site-packages', '/usr/local/lib/python3.6/site-packages']

 

 第三方模块:

导入第三方模块之前,需要先下载安装到本地python的安装目录, 使用 pip  install  模块名   进行下载

 

 

八、包

在创建了很多模块之后,将某些功能相近的文件组织在同一文件夹下,就形成了包;每个包下面必须有一个初始化文件 __init__.py ,   该文件可以为空

__init__.py 文件是用于规范 导入模块时使用 , 文件内容一般为 __all__ = ['模块名',......]     ,  导入使用 * 时会默认导入 列表中定义的模块

如何导入:

from 文件夹名 import 文件名
from 文件夹名.子文件夹 import 文件名

 

from package import test
from package.childer import demo

print(test.fun())
print(demo.fun())

 

 

九、错误与异常处理

捕获所有的异常类型,使用  except BaseException

import sys

try:
  a = int(input('请输入一个数字'))
  b = 10/a
  print(b)
except ValueError as e:      #  异常类型捕获处理
  print('输入数据类型错误')
except ZeroDivisionError as e:      #  异常类型捕获处理
  print('输入数据不能为0')
except :      #  异常类型捕获处理
  print('输入数据不能为0')
else:
  print(sys.exc_info()[0])        # 不知道异常类型的情况下使用,打印出错误类型
finally:
  print('不管有没有异常都执行')

 

 

十、 Python 对文件的处理

文件夹的操作:

os.path.exists(r"路径") :   判断某个文件夹是否存在

os.mkdir(path) :   创建一个文件夹,  不可以重复创建已经存在的文件夹

os.makedirs(path):  创建多个文件夹

import os

print(os.path.exists('a'))

os.mkdir('a')   # 创建 a 文件夹

os.makedirs('e/a')   # 创建 e 文件夹 并且里面有个a文件夹

 

os.walk(path):获得某个文件的信息,这个方法返回的是一个三元Tuple(dirpath, dirnames, filenames), 其中第一个为起始路径,第二个为起始路径下的文件夹,第三个为起始路径下的文件;

       dirpath 是一个 string , 代表目录的路径,

        dirnames 是一个list ,  包含了dirpath 下所有子目录的名字

        filenames 是一个list, 包含了非目录文件的名字,这些名字不包含路径信息,如果需要得到全路径,需要使用 os.path.join(dirpath, name)

import os

for item in os.walk('/Users/zhengweijie/Desktop/php'):
  print(item)

  #('/Users/zhengweijie/Desktop/php', ['.idea'], ['.DS_Store','test.php'])
#  ('/Users/zhengweijie/Desktop/php/.idea', ['inspectionProfiles'], ['modules.xml', 'php.iml', 'workspace.xml'])
# ('/Users/zhengweijie/Desktop/php/.idea/inspectionProfiles', [], [])

os.remove(path)    删除某个文件, 文件不存在报错  

os.rmdir(path)   删除空目录

os.removedirs(path)   递归删除空目录,   如 os.removedirs("c\d\f")    如果c d f 都是空目录,会全部删除

shutil.rmtree(path)   删除某个非空文件夹
 
os.listdir(path)   :    返回指定文件夹包含的文件或者文件夹的名称列表, 即指定文件夹下包含的第一级所有文件或者文件夹
os.path.isdir(path) : 判断路径是否为目录
os.path.join() :    将多个路径拼接返回
 
例子:彻底删除某个目录的方法:包含删除该目录下所有的文件和文件夹
import os

def deletNotNull (path):
  fileList = os.listdir(path)   #  获得该路径下所有的文件或者文件夹
  for t in fileList:            #  进行遍历
    if os.path.isdir(os.path.join(path, t)):      # 如果该文件是文件夹
      deletNotNull(os.path.join(path, t))         # 重复调用当前函数,进入下一层文件夹递归删除
    else:                                         #  否则是文件,直接删除
      os.remove(os.path.join(path,t))   
  for root, dirs, files in os.walk(path):         # 遍历获得该路径下所有文件夹路径
    os.removedirs(root)

 

 文件的操作:

使用 open('文件名',mode = '可操作模式')  方法获得一个文件对象, 可传多个参数,默认使用前两个参数   ; 操作完文件后,需要使用 close() 方法关闭文件

mode操作模式取值:

mode="r"   表示只读

mode="rb"   表示读取并转译为二进制 , 可使用 decode('utf-8')  方法转译回中文

mode="w"   表示写入,配合 write() 方法使用, 会覆盖原来的内容 ; 如果原文件不存在,会自动创建一个新文件

mode="a"    表示追加写入,不会覆盖原来的内容,文件不存在则创建一个新的文件

mode="r+"    表示可读可写,会覆盖原来的内容,无法创建不存在的文件

mode="w+"   表示可读可写,如果文件存在,则覆盖文件原来的内容,不存在则创建一个新文件

mode="a+"   表示可读可写,不会覆盖原来的内容,不存在则创建一个新文件

 

 

read() 方法 :  读取文件的所有内容

readline() 方法:  读取文件内容的第一行,使用循环可读取出每一行,依次读取

readlines() 方法:  读取文件的所有内容,并将每一行以列表形式返回

files = open('3.txt', mode="rb")
text = files.read().decode('utf-8')
print(text)

 

write() 方法: 往文件写入内容

files = open('3.txt', mode="w")
files.write('写入内容')
files.close()

 

 

fell() 方法: 返回文件内容的字节数,一个中文字符占多个字节

files = open('3.txt', mode="w")
files.write('我喜欢')
print(files.tell())   # 9

seek(offset, what) 方法: 设置文件内容的字节偏移数,即设置光标所在位置;  offset 表示偏移数,  what 表示偏移位置

seek(x, 0) :   从起始位置即文件首行首字符开始移动X个字符

seek(x, 1) :    从当前位置往后移动 X 个字符

seek(-x, 2) :   从文件的结尾往前移动X 个字符

 

tell() 方法: 返回文件当前的字符指示位置,理解为光标所在位置

flush() 方法: 刷新文件内部缓冲,刷新文件内容

isatty() 方法: 如果文件连接到一个终端设备返回True , 否则返回False

next() : 方法: 返回文件下一行

truncate([size]):  从文件首行首字符进行截断,截断文件为size 个字符 , 无size 表示从当前位置截断,截断位置之后的所有字符会被删除;  windows 下的换行代表2个字符

files = open('text.txt', mode="w+")
files.write('这是一个例子')
files.seek(0)    
print(files.read())
files.close()

 

使用第三方模块 chardet , 可检测文件内容的编码格式,方便使用 decode() 方法进行解码

import chardet

files = open('3.txt', mode="rb")
text = files.read()
print(chardet.detect(text))

 

递归:

递归的主要表现为自己调用自己,函数内部调用自己的称为递归函数

例子: 计算 1+2+3+4....+n的值

def sum(i):
  if i == 1:
    return i
  else:
    return sum(i-1)+i

print(sum(100))

 

序列化与反序列化:

序列化是指将对象状态转化为可保持或传输的格式的过程。与序列化相对的是反序列化,它将流转换为对象。这两个过程结合起来,可以轻松的存储和传输数据。

序列化与反序列化的目的:

1、以某种存储形式使自定义对象持久化

2、将对象从一个地方传递到另一个地方

3、使程序更具维护性

序列化:由于存在于内存中的对象都是暂时的,无法长期驻存,为了把对象的状态保持下来,这时需要把对象写入到磁盘或者其他介质中,这个过程就叫做序列化。将变量或者对象通过序列化,转化成字节流存储到文件(磁盘)或者通过网络传输到需要的机器上。因此,我们把变量或对象从内存中变成可存储或传输的过程称之为序列化

反序列化: 反序列化是序列化的反向操作,把已存在在磁盘或者其他介质中的对象,反序列化(读取)到内存中,以便后续操作,这个过程叫做反序列化

概括性来说序列化是指将对象实例的状态存储到存储媒体(磁盘或其他介质)的过程。在此过程中,先将对象的公共字段和私有字段以及类的名称(包括类所在的程序集)转换为字节流,然后再把字节流写入数据流。早随后对对象进行反序列化时,将创建出与原对象完全相同的副本。

pickle 模块

pickle.dump(obj, file, [protocol])  : 保存一个对象到指定文件中。  obj表示对象名, file指文件对象, protocol指存储协议,不传默认为0 ASCII协议

pickle.load(file)  :    从文件中读取一个对象,并将它重构为原来的Python对象,  file指文件对象

import pickle

obj = {'name':'小米', 'ega':18, 'height':165}
f = open('4.txt', mode="wb")    #  一般以二进制形式写入
pickle.dump(obj, f)
f.close()

f = open('4.txt', mode="rb")
newObj = pickle.load(f)
print(newObj)    

 

with 语句:with 语句适用于对资源进行访问的场合,确保不管适用过程中是否发生异常都会执行必要的清理操作,释放资源,比如使用文件后自动关闭、线程中锁的自动获取和释放等。

import pickle

with open('4.txt', mode="rb") as f:
  newObj = pickle.load(f)
  print(newObj)    

 关于网页爬虫:使用urllib.request 

import urllib.request

with open('test.txt', mode="wb") as f:
  f.write(urllib.request.urlopen('https://m.n8n8.cn/gsh/').read())

 

 

 

 

 

python 内置函数:

map(规则, 序列) :  表示按照某个规则映射某个序列,即按照某个规则遍历传入的序列,返回一个新的序列 。  这里的传入的规则为某个return函数, 一般跟 lambda匿名函数配合使用

list1 = [1,2,3,4,5,6]

print(list(map(lambda x: x*2, list1)))   #  [2, 4, 6, 8, 10, 12]

 

id(变量名) :     返回某个变量的内存地址 

str(变量名):   转换为字符串类型

int(变量名):   转换为整数类型

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

posted @ 2019-03-14 15:50  嘉爷  阅读(493)  评论(0编辑  收藏  举报