Python基础


数据类型

数字型(Number) 字符型(String) 布尔型(boolean) 空类型(None) 列表型(list) 元组型(tuple) 字典型(dict) 集合型(set)

标准数据类型

Python3 中有六个标准的数据类型:

1
Number(数字)

​ String(字符串)

1
List(列表)

​ Tuple(元组)
​ Dictionary(字典)

1
Sets(集合)

变量

对变量类型进行转换时可以使用Python的内置函数

  • int():将一个数值或字符串转换成整数,可以指定进制。
  • float():将一个字符串转换成浮点数。
  • str():将指定的对象转换成字符串形式,可以指定编码。
  • chr():将整数转换成该编码对应的字符串(一个字符)。
  • ord():将字符串(一个字符)转换成对应的编码(整数)。

Number(数字)

整型(Int) - 通常被称为是整型或整数,是正或负整数,不带小数点。Python3 整型是没有限制大小的,可以当作 Long 类型使用,所以 Python3 没有 Python2 的 Long 类型。
浮点型(float) - 浮点型由整数部分与小数部分组成,浮点型也可以使用科学计数法表示(2.5e2 = 2.5 x 102 = 250)
复数(complex) - 复数由实数部分和虚数部分构成,可以用a + bj,或者complex(a,b)表示, 复数的实部a和虚部b都是浮点型

数学函数

函数 返回值 ( 描述 )
abs(x) 返回数字的绝对值,如abs(-10) 返回 10
ceil(x) 返回数字的上入整数,如math.ceil(4.1) 返回 5
cmp(x, y) 如果 x < y 返回 -1, 如果 x == y 返回 0, 如果 x > y 返回 1。 Python 3 已废弃 。使用 使用 (x>y)- (x<y) 替换。

exp(x) 返回e的x次幂(ex), 如math.exp(1) 返回2.718281828459045
fabs(x) 返回数字的绝对值,如math.fabs(-10) 返回10.0
floor(x) 返回数字的下舍整数,如math.floor(4.9)返回 4
log(x) 如math.log(math.e)返回1.0,math.log(100,10)返回2.0
log10(x) 返回以10为基数的x的对数,如math.log10(100)返回 2.0
max(x1, x2,...) 返回给定参数的最大值,参数可以为序列。
min(x1, x2,...) 返回给定参数的最小值,参数可以为序列。
modf(x) 返回x的整数部分与小数部分,两部分的数值符号与x相同,整数部分以浮点型表示。
pow(x, y) x**y 运算后的值。
round(x [,n]) 返回浮点数x的四舍五入值,如给出n值,则代表舍入到小数点后的位数。
sqrt(x) 返回数字x的平方根。


String(字符串)

字符串常用内建函数 str1 = ‘’hello, world!’

str1.split( ) 通过指定分隔符对字符串进行切片,如果参数num 有指定值,则仅分隔 num 个子字符串

len() len函数计算字符串的长度 len(str1) # 13

str1.capitalize() 获得字符串首字母大写的拷贝 str1.capitalize() # Hello, world!

str1.upper() 获得字符串变大写后的拷贝 str1.upper() # HELLO, WORLD!

str1.find(str2, beg=0 end=len(string)) 检测 str2 是否包含在字符串中,如果指定范围 beg 和 end ,则检查是否包含在指定范围内,如果包含返回开始的索引值,否则返回-1

1
2
3
4
5
6
7
8
>>>str1 = 'abca'
>>> print(str1.find('a')) # 从下标0开始,查找在字符串里第一个出现的子串,返回结果:0
0
>>> print(str1.find('a', 1)) # 从下标1开始,查找在字符串里第一个出现的子串:返回结果3
3
>>> print(str1.find('3')) # 查找不到返回-1
-1
>>>

index(str, beg=0, end=len(string)) 跟find()方法一样,只不过如果str不在字符串中会报一个异常.

str1.startswith(str2) 检查字符串是否以指定的字符串开头

1
2
print(str1.startswith('He'))  	# False
print(str1.startswith('hel')) # True

str1.endswith(str2) 检查字符串是否以指定的字符串结尾

1
print(str1.endswith('!'))  # True

str1.center(width, '=') 将字符串以指定的宽度居中并在两侧填充指定的字符

1
print(str1.center(20, '='))		 #===hello, world!====

rjust ljust 右对齐/左对齐

str1.rjust(width, ' ') 将字符串以指定的宽度靠右放置左侧填充指定的字符

str1.isdigit() 检查字符串是否只由数字构成 ,返回 True 或 False

str1.isalpha() 检查字符串是否只由字母构成 ,返回 True 或 False

str1.isalnum() 检查字符串是否以数字和字母构成 ,返回 True 或 False

str1.strip() 获得字符串修剪左右两侧空格的拷贝

1
2
str1 = '      jackf1234@166.com  '
print(str1.strip()) # jackf1234@166.com

List(列表)

list1 = [1, 3, 5, 7, 100]

len(list1) 列表元素个数

max(list1) 返回列表元素最大值

min(list1) 返回列表元素最小值

list(对象) 将对象转换为列表 , 对象:字符串,元组,集合; 字典只能把键转成列表

list1.append(元素) 在列表末尾添加新的元素
list1.insert(下标, 元素) 在指定下标出添加一个元素,原来位置处的元素往后移动

list1.pop() 将列表中指定下标的元素删除, 如果默认不传递参数,则删除的是最后一个元素

list1.remove() 移除列表中指定的元素

list1.clear() 清除列表中所有的元素

list1.reverse() 用于反向列表中元素 等同于[::-1]

reversed(seq) 函数返回一个反转的迭代器。

seq – 要转换的序列,可以是 tuple, string, list 或 range

list1.sort() 应用在 list 上的方法, 返回的是对已经存在的列表进行操作

1
2
3
4
5
list1 = [4, 1, 45, 21, 2, 7]
# print(list1.sort()) 打印为None,没有返回值,只对原来列表排序
list2 = list1.sort()
print(list2) #结果还是为None
print(list1) #[1, 2, 4, 7, 21, 45]
1
2
3
4
5
6
#    0  1  2  3  4  5  6  7  8
a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
b = a[7:3:-1]
print(b) #[8, 7, 6, 5]
print(a[1:3:-1]) #None
print(a[3:1:-1]) #[4, 3]

Tuple(元组)

元组中的元素值是不允许修改的,但我们可以对元组进行连接组合

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

max(tuple) 返回元组中元素最大值。

min(tuple) 返回元组中元素最小值。

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


Dictionary(字典)

无序集合, key唯一,必须是不可变类型
访问获取方式:

  • ​ dict[key]
  • ​ dict.get(key)

添加元素:

  • ​ dict[key] = value # key为原字典中不存在的键

修改:

  • ​ dict[key] = balue # key为原字典中存在的键

dict.keys() 以列表返回字典中所有的键
dict.values() 以列表返回字典中所有的值
dict.items() 以列表返回可遍历的(键, 值) 元组数组 [(键, 值), (键, 值), (键, 值)]
dict.setdefault() 返回指定键的值,如果键不存在于字典中,将会添加键并将值设为默认值
dict.pop([key]) 删除指定键值对, 需传入参数 # 没有remove()方法
enumerate()用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中。

字典内置函数

dict1 = {‘name’:’shuaixiaohao’, ‘age’:22, ‘weight’:60}

len(dict) 计算字典元素个数,即键的总数。

print(len(dict1)) # 3

str(dict) 输出字典,以可打印的字符串表示。

print(str(dict1)) #{‘name’: ‘shuaixiaohao’, ‘age’: 22, ‘weight’: 60}
print(type(str(dict1))) #

type(variable) 返回输入的变量类型,如果变量是字典就返回字典类型。

字典内置函数

radiansdict.clear()
删除字典内所有元素
radiansdict.copy()
返回一个字典的浅复制
radiansdict.fromkeys()
创建一个新字典,以序列seq中元素做字典的键,val为字典所有键对应的初始值
radiansdict.get(key, default=None)
返回指定键的值,如果值不在字典中返回default值
key in dict
如果键在字典dict里返回true,否则返回false
radiansdict.items()
以列表返回可遍历的(键, 值) 元组数组
radiansdict.keys()
以列表返回一个字典所有的键
radiansdict.setdefault(key, default=None)
和get()类似, 但如果键不存在于字典中,将会添加键并将值设为default
radiansdict.update(dict2)
把字典dict2的键/值对更新到dict里
radiansdict.values()
以列表返回字典中的所有值
pop(key[,default])
删除字典给定键 key 所对应的值,返回值为被删除的值。key值必须给出。 否则,返回default值。
popitem()
随机返回并删除字典中的一对键和值(一般删除末尾对)。


Sets(集合)

set是无序,没有重复元素
set集合是不可改变的
创建一个空的集合 set1 = set(()); set1 = set([]); set1 = set({}) 注意:如果要创建一个空集合,你必须用 set() 而不是 {} ;后者创建一个空的字典
set.add(): 增加一个元素(重复元素不能添加) # 没有append()方法
set.remove():删除元素, 参数是元素
set.pop():删除最后一个元素
set1 & set2 交集
set1 | set2 并集
set1 - set2 差集
set1 ^ set2 交并集

1
2
dict-->set 取字典的键, 传入集合
set --> dict(错误) # 不能将集合转换成字典, 只有键, 没有值

三元条件运算

python中:

1
value1 if condition else value2

JavaScript中: conditon ? valuel1 : value2 问号前面的条件如果成立

1
2
3
function getStyle(elem) {
return window.getComputedStyle ? window.getComputedStyle(elem): elem.currentStyle;
}

迭代器与生成器

迭代器

迭代器是一个可以记住遍历的位置的对象。

迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。

迭代器有两个基本的方法:iter()next()

字符串,列表或元组对象都可用于创建迭代器

生成器

yield 函数被称为生成器(generator), 生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器 , 每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值, 并在下一次执行 next() 方法时从当前位置继续运行。调用一个生成器函数,返回的是一个迭代器对象。


函数

匿名函数

python 使用 lambda 来创建匿名函数。

所谓匿名,意即不再使用 def 语句这样标准的形式定义一个函数。

1
lambda [arg1 [,arg2,.....argn]]:expression  #arg-参数 ,expression-表达式

变量作用域

变量并不是在哪个位置都可以访问的,访问权限决定于这个变量是在哪里赋值的

  • L (Local) 局部作用域
  • E (Enclosing) 闭包函数外的函数中
  • G (Global) 全局作用域
  • B (Built-in) 内建作用域

以 L –> E –> G –>B 的规则查找,即:在局部找不到,便会去局部外的局部找(例如闭包),再找不到就会去全局找,再者去内建中找。

全局变量和局部变量

定义在函数内部的变量拥有一个局部作用域,定义在函数外的拥有全局作用域

global 和 nonlocal关键字

当内部作用域想修改外部作用域的变量时,就要用到global和nonlocal关键字了

1
2
3
4
5
6
7
import random
random.choice():返回列表,元祖,字典中的某一个值
random.choices():返回列表,元祖,字典中的指定个数值个值 k 关键字参数
random.random():返回0-1之间的数, [0, 1)
random.uniform():返回指定的一个区间范围的随机数 [, )
random.randint():返回指定区间范围的随机整数 [, ]
random.shuffle():将列表中的数据进行打乱排序
1
2
3
4
5
1. 不定长参数: *args
2. 关键字参数: **kw
3. 偏函数: 导入模块 import functools
functools.partical()就是创建一个新的函数.不需要自行定义函数.直接将结果赋值给一个变量,而 这个变量就是一个函数.这个函数的目的是将默认参数给固定住
4. 回调函数: 定义函数时,将函数名作为参数传递过来,然后在函数里边再次调用函数

偏函数

正则表达式

符号 解释 示例 说明
. 匹配任意字符 b.t 可以匹配bat / but / b#t / b1t等
\w 匹配字母/数字/下划线 b\wt 可以匹配bat / b1t / b_t等但不能匹配b#t
\s 匹配空白字符(包括\r、\n、\t等) love\syou 可以匹配love you
\d 匹配数字 \d\d 可以匹配01 / 23 / 99等
\b 匹配单词的边界 \bThe\b
^ 匹配字符串的开始 ^The 可以匹配The开头的字符串
\ 匹配字符串的结束\ .exe\ 匹配字符串的结束\ .exe 可以匹配.exe结尾的字符串
\W 匹配非字母/数字/下划线 b\Wt 可以匹配b#t / b@t等但不能匹配but / b1t / b_t等
\S 匹配非空白字符 love\Syou 可以匹配love#you等但不能匹配love you
\D 匹配非数字 \d\D 可以匹配9a / 3# / 0F等
\B 匹配非单词边界 \Bio\B
[] 匹配来自字符集的任意单一字符 [aeiou] 可以匹配任一元音字母字符
[^] 匹配不在字符集中的任意单一字符 [^aeiou] 可以匹配任一非元音字母字符
* 匹配0次或多次 \w*
+ 匹配1次或多次 \w+
? 匹配0次或1次 \w?
{N} 匹配N次 \w{3}
{M,} 匹配至少M次 \w{3,}
{M,N} 匹配至少M次至多N次 \w{3,6}
\ 分支 foo\ bar 可以匹配foo或者bar
(?#) 注释
(exp) 匹配exp并捕获到自动命名的组中
(?\exp) 匹配exp并捕获到名为name的组中
(?:exp) 匹配exp但是不捕获匹配的文本
(?=exp) 匹配exp前面的位置 \b\w+(?=ing) 可以匹配I’m dancing中的danc
(?<=exp) 匹配exp后面的位置 (?<=\bdanc)\w+\b 可以匹配I love dancing and reading中的第一个ing
(?!exp) 匹配后面不是exp的位置
(? 匹配前面不是exp的位置
*? 重复任意次,但尽可能少重复 a.ba.?b 将正则表达式应用于aabab,前者会匹配整个字符串aabab,后者会匹配aab和ab两个字符串
+? 重复1次或多次,但尽可能少重复
?? 重复0次或1次,但尽可能少重复
{M,N}? 重复M到N次,但尽可能少重复
{M,}? 重复M次以上,但尽可能少重复

re模块中的核心函数

1
2
3
4
re.match(pattern, string, flags=0)
pattern 匹配的正则表达式
string 要匹配的字符串
flags 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等
函数 说明
compile(pattern, flags=0) 编译正则表达式返回正则表达式对象
match(pattern, string, flags=0) 用正则表达式匹配字符串 成功返回匹配对象 否则返回None
search(pattern, string, flags=0) 搜索字符串中第一次出现正则表达式的模式 成功返回匹配对象 否则返回None
split(pattern, string, maxsplit=0, flags=0) 用正则表达式指定的模式分隔符拆分字符串 返回列表
sub(pattern, repl, string, count=0, flags=0) 用指定的字符串替换原字符串中与正则表达式匹配的模式 可以用count指定替换的次数
fullmatch(pattern, string, flags=0) match函数的完全匹配(从字符串开头到结尾)版本
findall(pattern, string, flags=0) 查找字符串所有与正则表达式匹配的模式 返回字符串的列表
finditer(pattern, string, flags=0) 查找字符串所有与正则表达式匹配的模式 返回一个迭代器
purge() 清除隐式编译的正则表达式的缓存
re.I / re.IGNORECASE 忽略大小写匹配标记
re.M / re.MULTILINE 多行匹配标记

面向对象

面向对象的三个基本特征是:封装、继承、多态

封装:

​ 封装是实现面向对象程序设计的第一步,封装就是将数据或函数等集合在一个个的单元中(我们称之为类)。被封装的对象通常被称为抽象数据类型。 隐藏复杂的现实细节,暴露简单的调用接口。

封装的意义:
  封装的意义在于保护或者防止代码(数据)被我们无意中破坏。在面向对象程序设计中数据被看作是一个中心的元素并且和使用它的函数结合的很密切,从而保护它不被其它的函数意外的修改。

  1. 保护数据成员,不让类以外的程序直接访问或修改,只能通过提供的公共的接口访问==>数据封装。
  2. 方法的细节对用户是隐藏的,只要接口不变,内容的修改不会影响到外部的调用者==>方法封装。
  3. 当对象含有完整的属性和与之对应的方法时称为封装。
  4. 从对象外面不能直接访问对象的属性,只能通过和该属性对应的方法访问。
  5. 对象的方法可以接收对象外面的消息。

继承:

​ 从已有的类创建新类的过程 提供继承信息的称为父类(超类/基类) 得到继承信息的称为子类(派生类)。继承主要实现重用代码,节省开发时间。

  1. 在类名后边的括号里一般写的是基类的类名
  2. 子类中继承自父类(基类),则父类的成员属性和成员方法都可以被子类所继承
  3. 父类中私有的成员属性不能继承给子类的

多态:

“一个接口,多种方法”

​ 同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。

多态的三个条件:

  1. 继承的存在(继承是多态的基础,没有继承就没有多态)
  2. 子类重写父类的方法(多态下调用子类重写的方法)
  3. 父类引用变量指向子类对象(子类到父类的类型转换)

数据抽象一找到和对象相关的数据一属性( 名词)

行为抽象一 找到和对象相关的行为一方法(动词)

__slots__

​ 限定自定义类型的对象只能绑定某些属性,可以通过在类中定义_slots\_变量来进行限定。需要注意的是__slots__的限定只对当前类的对象生效,对子类并不起任何作用。

1
2
3
class Person(object):
# 限定Person对象只能绑定_name, _age和_gender属性
__slots__ = ('_name', '_age', '_gender')

魔法方法

区分开函数和方法的含义:

  1.函数:类外部定义的,跟类没有直接关系的;形式: def func(*argv):

  2.方法:class内部定义的函数(对象的方法也可以认为是属性);分为两种:

    ① python自动产生的(魔法方法):一般形式为 __func__(),python会在对应的时机自动调用该函数;

    ② 人为自定义的方法:一般和普通函数没有区别,只是定义在了class中而已

  3.方法与函数的区别:

    方法可认为是函数的特殊情况;

    ① 方法定义在class内部

    ② 方法的第一个参数应为 cls(类方法) 或者 self(实例方法)

列出几个基本魔法方法:

__new__(cls[,*argv])

  • __new__ 是在一个对象实例化的时候所调用的第一个方法
  • 它的第一个参数是这个类,其他的参数是用来直接传递给 __init__ 方法
  • _new__ 决定是否要使用该 \_init__方法,因为 __new__ 可以调用其他类的构造方法或者直接返回别的实例对象来作为本类的实例,如果 __new__ 没有返回实例对象,则 __init__ 不会被调用
  • __new__ 主要是用于继承一个不可变的类型比如一个 tuple 或者 string

__init__(self,[…])

  • 类的初始化方法 ,当一个实例对象被定义时调用

    *__del__(self)**

  • 析构器,当一个实例被析构时调用

  • _new__ 和 \_init__ 是对象的构造器, __del__ 是对象的销毁器

Python内置装饰器

在Python中有三个内置的装饰器,都是跟class相关的:staticmethodclassmethodproperty

  • staticmethod 是类静态方法,其跟成员方法的区别是没有 self 参数,并且可以在类不进行实例化的情况下调用
  • classmethod 与成员方法的区别在于所接收的第一个参数不是 self (类实例的指针),而是cls(当前类的具体类型)
  • property 是属性的意思,表示可以通过通过类实例直接访问的信息

    类方法、静方法 都是通过给类发消息来调用的

    实例方法 发给对象的消息 在类创建对象后,实例方法才能被使用,使用格式为:对象名.实例方法

    ​ 名。实例方法可以使用该方法所在类的所有静态成员和实例成员。

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
from abc import abstractmethod, ABCMeta

# 面向对象的三大支柱 - 封装 / 继承 / 多态
# 封装 - 隐藏复杂的实现细节 暴露简单的调用接口
# 继承 - 从已有的类创建新类的过程 提供继承信息的称为父类(超类/基类) 得到继承信息的称为子类(派生类)
# 多态 - 见下面


# 在创建类时通过指定metaclass=ABCMeta可以将一个类声明为抽象类
# 所谓抽象类就是不能创建对象的类 它存在价值是留给它的子类去继承
# 经验: 我们强烈建议将用来继承的类声明为抽象类
class Employee(object, metaclass=ABCMeta):
def __init__(self, name):
self._name = name

@property
def name(self):
return self._name[:-1] + '*'

# 被abstractmethod包装器修饰的方法是抽象方法
# 所谓抽象方法就是没有实现专门留给子类去重写的方法
# 如果子类没有重写这个抽象方法 那么子类相当于也是抽象类 不能创建对象
@abstractmethod
def get_salary(self):
pass


class Manager(Employee):
def get_salary(self):
return 12000

class Programmer(Employee):
def __init__(self, name):
super().__init__(name)
self._working_hour = 0

@property
def working_hour(self):
return self._working_hour

@working_hour.setter
def working_hour(self, working_hour):
self._working_hour = working_hour if working_hour > 0 else 0

def get_salary(self):
return 150 * self._working_hour


class Salesman(Employee):
def __init__(self, name):
super().__init__(name)
self._sales = 0

@property
def sales(self):
return self._sales

@sales.setter
def sales(self, sales):
self._sales = sales

def get_salary(self):
return 1500 + self._sales * 0.05

def main():
emp_list = [Manager('王大锤'), Programmer('骆昊'),
Programmer('李大嘴'), Salesman('白元芳')]
for emp in emp_list:
if isinstance(emp, Programmer): #判断一个对象是否是一个已知的类型
hour = int(input('请输入%s本月工作时间: ' % emp.name))
emp.working_hour = hour
elif isinstance(emp, Salesman):
sales = float(input('请输入%s本月销售额: ' % emp.name))
emp.sales = sales
# 多态 - 给同样的对象发送同样的消息(同样的引用调用同样的方法)做了不同的事情
# 实现多态最关键的就是子类对父类已有方法进行重写 不同的子类给出不同的实现版本
print('%s月薪为¥%.2f元' % (emp.name, emp.get_salary()))


if __name__ == '__main__':
main()

异常处理

1
2
3
4
5
6
7
8
9
try:
print('try...')
r = 10 / 0
print('result:', r)
except ZeroDivisionError as e:
print('except:', e)
finally:
print('finally...')
print('END')

try语句按照如下方式工作;

  • 首先,执行try子句(在关键字try和关键字except之间的语句)
  • 如果没有异常发生,忽略except子句,try子句执行后结束。
  • 如果在执行try子句的过程中发生了异常,那么try子句余下的部分将被忽略。如果异常的类型和 except 之后的名称相符,那么对应的except子句将被执行。最后执行 try 语句之后的代码。
  • 如果一个异常没有与任何的except匹配,那么这个异常将会传递给上层的try中。
  • 无论有没有异常finally语句被执行。

一个 try 语句可能包含多个except子句,分别来处理不同的特定的异常。最多只有一个分支会被执行。

处理程序将只针对对应的try子句中的异常进行处理,而不是其他的 try 的处理程序中的异常。

一个except子句可以同时处理多个异常,这些异常将被放在一个括号里成为一个元组,例如:

1
2
except (RuntimeError, TypeError, NameError):
pass

​ try except 语句还有一个可选的else子句,如果使用这个子句,那么必须放在所有的except子句之后。这个子句将在try子句没有发生任何异常的时候执行

​ 使用 else 子句比把所有的语句都放在 try 子句里面要好,这样可以避免一些意想不到的、而except又没有捕获的异常。

1
异常处理并不仅仅处理那些直接发生在try子句中的异常,而且还能处理子句中调用的函数(甚至间接调用的函数)里抛出的异常。

文件

读、写文件

1
open(filename, mode)

mode:决定了打开文件的模式:只读,写入,追加等

操作模式 具体含义

1
2
3
4
5
6
7
**'r'**			读取 (默认)
**'w'** 写入(会先截断之前的内容)
**'x'** 写入,如果文件已经存在会产生异常
**'a'** 追加,将内容写入到已有文件的末尾
**'b'** 二进制模式
**'t'** 文本模式(默认)
**'+'** 更新(既可以读又可以写)

with语句来自动帮我们调用close()方法 (关闭文件)

with 语句就可以保证文件之类的对象在使用完之后一定会正确的执行他的清理方法

1
with open("myfile.txt") as f:

文件对象的方法

fileObject.read([size])

​ 从文件读取指定的字节数,如果未给定或为负则读取所有。

fileObject.write()

​ 写文件 # 如果要写入字符串以外的数据,先将他转换为字符串

fileObject.close()

​ 关闭文件

fileObject.readline([size])

​ 读取整行内容,包括\n字符, 如果给定参数则从文件开始读取指定的字符个数

fileObject.readlines([sizeint])

​ 读取所有行并返回列表,若给定sizeint>0,返回总和大约为sizeint字节的行, 实际读取值可能比 sizeint 较大, 因为需要填充缓冲区。

f.tell()

​ 返回一个整数,表示当前文件指针的位置(就是到文件头的比特数).

f.seek(偏移量,[起始位置])

​ 用来移动文件指针 #偏移量:单位:比特,可正可负起始位置:0-文件头,默认值;1-当前位置;2-文件尾

操作文件和目录

os模块:在这个模块中给我们封装好了系统操作的功能函数(方法)

import os

  • os.getcwd() 返回当前的工作目录 # 获取绝对路径
  • os.listdir(path) 返回指定的文件夹包含的文件或文件夹的名字的列表
  • os.mkdir(path) 在当前目录下创建新的目录
  • os.rmdir(path) 删除目录, 只能删除空目录
  • os.rename(src, dst) 对文件进行重命名
  • os.stat(file) 获取文件属性
  • os.remove(file) 删除文件 #可以将本文件删除
  • os.path.join(path1, path2) 路径拼接
  • os.path.split(path) 拆分路径 # 返回一个元组(目录, 最后一个文件/目录名称)
  • os.path.splitext(path) 获取文件的或站名
  • os.path.exists(path) 判断文件/目录是否存在
  • os.path.isfile(path) 判断是否是文件
  • os.path.getsize(file) 获取文件的大小
  • os.path.dirname(path) 获取当前文件的目录
  • os.path.basename(path) 获取当前文件/目录名

StringIO

很多时候,数据读写不一定是文件,也可以在内存中读写

  1. StringIO模块主要用于在内存缓冲区中读写数据。模块是用类编写的,只有一个StringIO类,
  2. # 所以它的可用方法都在类中。此类中的大部分函数都与对文件的操作方法类似。
1
2
3
4
5
6
7
8
9
10
>>> from io import StringIO
>>> f = StringIO()
>>> f.write('hello')
5
>>> f.write(' ')
1
>>> f.write('world!')
6
>>> print(f.getvalue())
hello world!

getvalue()方法用于获得写入后的str。

BytesIO

StringIO操作的只能是str,如果要操作二进制数据,就需要使用BytesIO。

BytesIO实现了在内存中读写bytes,我们创建一个BytesIO,然后写入一些bytes

1
2
3
4
5
6
>>> from io import BytesIO
>>> f = BytesIO()
>>> f.write('中文'.encode('utf-8'))
6
>>> print(f.getvalue())
b'\xe4\xb8\xad\xe6\x96\x87'

进程和线程

进程:是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位

线程:是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源

一个程序至少有一个进程,一个进程至少有一个线程。线程是最小的执行单元,而进程由至少一个线程组成。

多进程

​ Unix/Linux操作系统提供了一个fork()系统调用,它非常特殊。普通的函数调用,调用一次,返回一次,但是fork()调用一次,返回两次,因为操作系统自动把当前进程(称为父进程)复制了一份(称为子进程),然后,分别在父进程和子进程内返回。 fork()是os模块里的函数

​ 子进程永远返回 0,而父进程返回子进程的ID。这样做的理由是,一个父进程可以fork出很多子进程,所以,父进程要记下每个子进程的ID,而子进程只需要调用getppid()就可以拿到父进程的ID。

Windows没有 fork调用multiprocessing模块就是跨平台版本的多进程模块。

multiprocessing模块提供了一个Process类来代表一个进程对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from multiprocessing import Process
import os

# 子进程要执行的代码
def run_proc(name):
print('Run child process %s (%s)...' % (name, os.getpid()))

if __name__=='__main__':
print('Parent process %s.' % os.getpid()) #getpid()取得进程识别码
p = Process(target=run_proc, args=('test',)) #创建一个Process实例
print('Child process will start.')
p.start() #启动子进程
p.join() #等待子进程结束后再继续往下运行
print('Child process end.')

执行结果如下:

1
2
3
4
Parent process 928.
Process will start.
Run child process test (929)...
Process end.

创建子进程时,只需要传入一个执行函数和函数的参数,创建一个Process实例,用 start()方法启动。

join()方法可以等待子进程结束后再继续往下运行,通常用于进程间的同步

Pool

如果要启动大量的子进程,可以用进程池的方式批量创建子进程:

多线程

Python的标准库提供了两个模块:_threadthreading_thread 是低级模块,threading 是高级模块,对 _thread 进行了封装。绝大多数情况下,我们只需要使用 threading 这个高级模块。

启动一个线程就是把一个函数传入并创建 Thread 实例,然后调用 start() 开始执行

网络编程

协议- protocol- 通信双方对话的规范和标准

IP.Internet Protocol- 寻址和路由
www.baidu.com---> 180.97.33.108

TCP和UDP是在IP协议之上构建的传输协议它们能够提供传输数据的服务
TCP提供了可靠传输服务
TCP- Transfer Control Protocol
握手机制+冗余校验—> 重发一次

TCP.Transfer Control Protocol I
1.可靠通信[数据不传丢也不传错]
滑动窗口机制
2.流量控制(自动调节发送数据的速度
3.拥塞控制(网络拥堵时会降低发送速度)

QQ 微信.应用级
QQ— ICQ— OICQ
HTTP— Hyper-Text Transfer Protocol
HTTPS— Secure
SMTP– Simple Mail Transfer Protocol
POP3— Post Office Protocol version 3
IMAP—Internet Mail Access Protocol
xerox— macintosh— Windows

URL— Uniform Resource Locator
协议://域名或IP地址:80/路径/资源名

网络API(应用程序编程接口) / 网络

1
2
3
4
5
6
7
8
9
requests.get()用于请求目标网站,类型是一个HTTPresponse类型
import requests
response = requests.get('http://www.baidu.com')
print(response.status_code) # 打印状态码
print(response.url) # 打印请求url
print(response.headers) # 打印头信息
print(response.cookies) # 打印cookie信息
print(response.text) #以文本形式打印网页源码
print(response.content) #以字节流形式打印

TCP编程

Socket是网络编程的一个抽象概念。通常我们用一个Socket表示“打开了一个网络链接”,而打开一个Socket需要知道目标计算机的IP地址和端口号,再指定协议类型即可。

服务器

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
30
31
32
33
34
35
36
37
#创建服务器发文件
from io import SEEK_END
from socket import socket, SOCK_STREAM, AF_INET
from datetime import datetime
from time import sleep


def main():
# 1.创建套接字对象并指定使用哪种传输服务
server = socket(family=AF_INET, type=SOCK_STREAM)
# 2.绑定IP地址和端口(区分不同的服务)
server.bind(('10.7.152.130', 9090))
# 3.开启监听 - 监听客户端连接到服务器
server.listen(512)
print('服务器启动开始监听...')
with open('guido.jpg', 'rb') as f:
data = f.read()
f.seek(0, SEEK_END)#设置文件读取指针在文件当前位置
file_len = f.tell()#返回文件当前位置指针
# 4.通过循环接收客户端的连接并作出相应的处理(提供服务)
while True:
# accept方法是一个阻塞方法 如果没有客户端连接到服务器这个方法就会阻塞代码不会向下执行
client, addr = server.accept()
# 5.发送数据
client.send('guido.jpg'.encode('utf-8'))
client.send(str(file_len).encode('utf-8'))
total = 0
while total < file_len:
client.send(data[total:total+1024])
total += 1024
sleep(0.001)
# 6.断开连接
client.close()


if __name__ == '__main__':
main()

客户端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
from socket import socket


def main():
# 创建一个socket
client = socket()
# 建立连接:
client.connect(('10.7.152.130', 9090))
filename = client.recv(1024).decode('utf-8')
print(filename)
file_len = int(client.recv(1024).decode('utf-8'))
print(file_len)
with open('C:/Users/Administrator/Desktop/' + filename,'wb') as f:
total = 0
while total < file_len:
date = client.recv(1024)
f.write(date)
total += 1024
print('图片已保存')

if __name__ == '__main__':
main()

最后更新: 2018年05月26日 13:18

原始链接: http://yoursite.com/2018/05/17/Python基础/

× 请我吃糖~
打赏二维码