数值类型

类型 关键字 数据
整型 int 整数,无限
浮点型 float 小数
复数 complex 复数由实数部分和虚数部分构成

关键字

算术 引入 异常 控制 操作与状态 返回退出 定义
and import except while del return lambda
or as try if assert yield class
in from finally else True continue global
is raise elif False pass def
not with for None break nonlacal

基础操作与使用

输入

1
2
3
4
5
6
7
8
9
10
# 通过 input 可以直接完成一个交互式的输入
value = input('请输入一个整数: ')

# 输入的任何数据最终都会是一个字符串
print(value, type(value))

# 通过强制类型转换或 eval 函数可以转换类型
value = int(input('请输入第二个数: '))
print(value, type(value))

输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 使用 print 进行内容的输出,可以输出不定长度不定类型的值
print(1, '1', 1.1, [1, ], (1, ))

# 在使用 print 进行输出的时候,通过参数可以指定一些格式
print(1, 2, 3, 4, 5, 6, sep='*', end='这里是结尾')

# 格式化输出,使用 % 进行格式化输出,字符串语法支持
print('%5.2f + %d = %d' % (1, 2, 1+2))

# 格式化输出,使用字符串的内置方法 format,字符串内置方法
print('{0:.3f}, {1:10d}, {0:.3f}'.format(1, 2))

# 格式化输出,使用 f'' 字符串进行输出,语法支持
print(f'{1:.2f} + {2} = {1+2}')

函数的定义

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
# 函数定义的简单例子
def my_max(value1=0, value2=0):
# 类似三目运算符的写法
return value1 if value1 > value2 else value2


# 新的写法,可以限制传入的类型
def my_min(value1: int, value2: int) -> int:
return value1 if value1 > value2 else value2


# pass 类似于 C 语言中的单个分号,即什么也不做,如果一个
# 函数没有显示的指定返回值,那么就返回 None
def no_return():
pass


print(no_return())


# 参数的传递: 位置传参,按照定义顺序传参
print(my_min(10, 20))

# 参数的传递: 关键字传参,按照形参名传参(很常见)
print(my_min(value2=10, value1=20))

运算符的使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 算数运算符: 幂运算 **
print(2 ** 1024)

# 算数运算符: 除法运算 /(真除法) //(向下取整除法)
print(10 / 10, 10.0 / 3)
print(10 // 3, -10.0 // 3)

# 比较运算 == 和身份运算符 is
l1 = [1, 2, 3]
l2 = l1
print(hex(id(l1)), hex(id(l2)), l1 == l2, l1 is l2)
l2 = l1.copy()
print(hex(id(l1)), hex(id(l2)), l1 == l2, l1 is l2)

# 成员关系运算符: 判断某元素是否在某容器中
print('a' in 'abc', 'd' in 'abc')

选择结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 判断用户输入的用户名和密码是否符合长度且匹配

# 接收用户的输入
username = input('username: ')
password = input('password: ')

# 判断用户输入的长度是否准确
if len(username) >= 8 and len(password) >= 8:
# if 后面直接添加表达式,结尾必须添加冒号(:)
if username == 'username' and password == 'password':
# if 后面的语句必须拥有一级缩进,并且所有存在一级缩进
# 的语句都被认为是语句块的一部分,累哦四花括号作用域
print('登录成功,跳转至个人中心...')
print('这里是第二条语句,同样是输出的')
else:
print('用户名或密码的长度不够')


列表

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
# 列表的基础知识: 内置的序列类型,可以看作是加强版本的数,通过中括号
# [] 进行定义,其中不要求元素的类型是一致的,并且长度是可变的
print([1, 2, 3, 4, 5], type([]))
print([1, 1.1, '1', [1]])

# 算数运算
print([1] + [2]) # 将参与运算的列表组合成新的列表
print([1, 2] * 3) # 将列表的元素重复 3 次
print(3 in [0, 1, 2]) # 判断是否在列表中
print([1, 2, 3] == [3, 2, 1]) # 比较运算符

# 全局函数
print(len([1, 2, 3]))
print(min([1, 2, 3]))
print(max([1, 2, 3]))
print(list(reversed([1, 2, 3])))
print(list(sorted([1, 2, 3])))

# 内置方法
l = [1, 2, 3, 4, 5]
l.append(6)
print(l) # 在结尾添加元素
l.insert(0, 0)
print(l) # 在指定位置添加
l.remove(3)
print(l) # 删除某元素(元素)
l.pop(0)
print(l) # 删除某元素(索引),返回删除的内容
l.extend([1,2,3,4])
print(l) # 类似列表的加法运算符

# 切片操作(序列操作) l[a:b:c]
l = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print(l[:3], l[:4]) # [起始位置, 结束的索引(不包含)]
print(l[3:], l[4:]) # [起始的索引(包含), 结束位置]
print(l[::2], l[::3]) # [::间隔的个数(步长)]
print(l[:-1]) # [:负数] 倒数第n个的前一个
print(l[::-1]) # [::负数] 逆序开始计算步数
print(l[1:7:3]) # 从下标 1 开始,到下标 7 的前一个,每次遍历+3

# 元组类型: 可以看作不变的列表,操作方式类似列表,使用 , 定义
print((1,), type((1,)))

# 元组的打包和解包(打包)
t = 1, 2, 3, 4, 5
# 元组的打包和解包(解包): 解包的过程中前面的变量数量和元组的元素数量必须保持一致
a, b, c, d, e = t

# 元组打包解包的例子
a = 1
b = 2
# 将 b 和 a 的值,也就是 2 和 1 打包成一个临时的元组,
# 然后进行解包,将 2 和 1 分别赋值给对应位置的 a 和 b
a, b = b, a


# 打包可以让函数返回多个参数,解包可以接收多个参数
def return_more():
return 1, 2, 3


# 通过解包接收到了多个返回值
value1, value2, value3 = return_more()

字典

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
# 字典存储的是键值对,可以通过 {}的方式定义字典
print({'1': 1, '2': 2, '3': 3}, {})

d = dict()
# 通过索引添加键来访问对应的值,第一次赋值时会添加,接下来的操作就是修改
d['小明'] = 99
print(d) # 添加
d['小明'] = 0
print(d) # 修改
del d['小明']
print(d) # 删除

# 不能访问不存在的键,在使用前通常会判断是否拥有键
if '小明' in d:
print(d['小明'])

# 可变类型,元素可以被修改的类型: list dict set
# 不可变类型,元素不可以被修改的类型: int float bool str tuple

# 字典的键必须时不可变类型
d = {1: 1, '1': 1, True: 1, 1.1: 1, (1,): 1}

# 用于获取到字典内的一些信息
print(d.items())
print(d.values())
print(d.keys())


# 集合类型: 通过 {值,值,值} 定义非空集合,空集合使用set()定义
# set 要求所有的数据必须时常量,且唯一
print({1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 7, 6, 5, 4, 3, 2, 1})

# 可以通过集合来保存一些唯一的数据
print(list(set([1, 2, 3, 4, 5, 6, 7, 8])))

# 集合可以用于执行数学运算中的集合运算 | ^ - +

深拷贝与浅拷贝

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
l1 = [1, 2, 3, 4, 5, 6, 7, 8, 9]

# 对列表进行赋值操作,执行的实际是浅拷贝
l2 = l1
print(hex(id(l1)), hex(id(l2)))

# 如果是浅拷贝,两个变量指向同一个地址,一方更改,另一方也受影响
l2[0] = 10
print(l1, l2)

l1 = [1, 2, 3, 4, 5, 6, 7, 8, 9]

# 通过 copy 方法进行深拷贝
l2 = l1.copy()
print(hex(id(l1)), hex(id(l2)))

# 拥有各自独立的空间,不会影响另外一个
l2[0] = 10
print(l1, l2)


# 动态类型: 类型在运行过程中确定,可以改变,一般不用在定义(如果有定义)时指定类型
# 静态类型: 类型在编译时确定,运行期间不变,始终保存定义时所提供的类型

# 强类型: 不同类型的变量,所能够执行的操作是不同的,例如整数相乘是乘法,字符串乘法是重复
# 弱类型: 运算不考虑类型,可以为任何类型提供计算

while循环

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
# 循环,使用 while 编写循环语句,和 C 相同

number = 1
while number <= 100:
print(number, end=' ')
number += 1
print('')

# for 语句的使用: 可以用于遍历所有的可迭代类型,每次循环从序列中获取第(循环次数)个的元素,
# 将元素赋值给 for 和 in 中间所提供的变量中,可以被直接的访问到
for letter in 'hello 15pb':
print(letter)

# 使用 range 可以快速生成一个指定规则的列表,参数同切片
print(list(range(1, 100, 3)))

# 通过 range 生成一个可迭代序列,从中取出元素,并输出
for value in range(101):
print(value)


# while 一般用于不确定的循环,for 一般用于序列的遍历
# break 和 continue 和 C++ 的完全一致,对于break,for 和 while 有扩展语法

for i in range(100):
# 对于 for else 或者 while else 语句,如果采用 break 跳出
# 循环就不执行 else,如果正常退出则执行
pass
else:
print('正常退出')

for循环

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
l = [1, 2, 3, 4, 5, 6, 7, 8, 9]

# 使用 for 遍历的几种方式: 值的遍历
for item in l:
print(item, end=' ')
print('')

# 使用下标的方式进行遍历
for index in range(len(l)):
print(f'l[{index}]={l[index]}', end=' ')
print('')

# 通过枚举的方式进行索引
for index, item in enumerate(l):
print(f'l[{index}]={item}', end=' ')
print('')

d = {'小明': 100, "小红": 101, '小刚': 99}

# 字典的遍历方式: 键,默认使用字典名就是 keys
for key in d.keys():
print(f'd[{key}]={d[key]}', end=' ')
print('')

# 字典的遍历方式: 值
for value in d.values():
print(f'{value}', end=' ')
print('')

# 字典的遍历方式: 键值对
for key, value in d.items():
print(f'd[{key}]={value}', end=' ')
print('')

生成式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 列表生成式: 快速生成列表
print([i for i in range(1000)]) # 生成指定序列
print([i for i in range(1000) if i % 2 == 0]) # 生成指定序列 + 判断
print([i**2 for i in range(1000) if i % 2 == 0]) # 生成指定序列 + 判断 + 表达式
print([i*j for i in range(1, 10) for j in range(1, 10)])

import os
dir_base = r'D:\Microsoft\Visual Studio 2019\Common7\IDE\\'
print([os.path.splitext(path) for path in os.listdir(dir_base) if os.path.isfile(dir_base+path)])

# 元组生成式,改成圆括号
# 字典生成式,改成键值对的花括号
# 集合生成式,改成花括号

global关键字

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
# 全局变量: 定义在所有函数之外的变量
g_number = 0


# 局部变量: 定义在任何一个函数之内的变量
def function1():
l_number = 1
# 分别用于输出当前的全局变量以及所在作用域的局部变量
print(globals(), locals())


function1()


# 尝试在函数中访问一个全局变量
def function2():
# 在局部空间中可以直接访问全局变量
print(g_number)


function2()


def function3():
# 一旦尝试在函数内修改全局变量,实际上会定义出一个
# 和全局变量同名的局部变量
g_number = 10000
print(locals(), globals())


function3()


def function4():
# 通过 global 关键字,可以声明使用的是全局范围内的 g_number
global g_number
g_number = 100000000
print(locals(), globals())


function4()


def function5():
# 如果想在函数内定义一个全局变量,也可以使用 global
global g_value2
g_value2 = 0x12345
print(locals(), globals())


function5()

模块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 任何一个以 .py 结尾的文件,都被成为模块,可以使用 import 语句导入
# 导入的时候首先需要找到目标模块,接下来将目标模块转换成字节码,使用
# PVM执行字节码,由于这是一个十分消耗性能的事情,所以 python 只允许
# 我们对一个模块直接进行一次导入
import module
import module

# 如果一定想要代码被执行多遍,可以使用内置模块 importlib
import importlib
importlib.reload(module)

# 如何使用模块中的内容(概念类似C++中的头文件和命名空间)
import module # 类似于 #include <iostream>
print(module.module_value1)

from module import module_value2 # 类似于在包含头文件的基础上 using std::name
print(module_value2)

from module import * # 在包含头文件的基础上 using namespace std
print(module_value3)

# 单下划线开头的模块全局变量只能使用命名空间访问
print(module._module_private_value)

类的定义

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
# class 开头后面紧跟类名,类名的首字母应该大写,后面的括号中是父类
# python3 定义的类称之为新式类,无论是否显式说明父类的 object,默
# 认都继承自 object,并且继承下来了一些内置的方法
class Student(object):
# 类内直接定义了一些变量,被称为[类]属性,所有的类属性
# 归类所有,能够被任何一个实例访问到,类似于静态变量
count = 0
books = []

# 构造访问,任何一个类都拥有名称为 __init__ 的构造方法,
# 当一个实例被创建之后,会被自动的调用
def __init__(self, name, age):
# 所有使用 self 以及实例名创建的变量都成为实例属性
# 每一个实例都拥有自己的实例属性,可以动态添加
self.name = name
self.age = age
print('这是一个构造方法')

# 任何一个类都拥有名称为 __del__ 的析构方法
def __del__(self):
print('这是一个析构方法')


# 如果存在构造方法,那么创建实例的时候,必须提供除
# self 以外的其它所有参数,self 类似于 this,表示
# 调用方法的是哪一个实例
objStudent1 = Student("xiaoming", 19)

类属性的使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 定义一个类,类内添加了类属性
class Demo(object):
# 一个类属性
class_value = 0


demo = Demo()
# 想要访问类属性,可以使用类名以及实例名(不推荐)
print(demo.class_value)
print(Demo.class_value)

# 对于类属性的修改,
demo.class_value = 100 # 创建了一个同名的实例属性
print(Demo.class_value)
Demo.class_value = 200 # 修改类属性只能使用类名
print(Demo.class_value)

# 动态增减类属性的方式
# 增加: 通过类名或类方法中的 cls 关键字可以动态添加
Demo.class_value2 = 1000
print(Demo.__dict__) # 包含类内所有的属性组合的键值对
# 删除: 通过关键字 del 进行删除
del Demo.class_value
print(Demo.__dict__)

实例属性的使用

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
# 一个类,包含了实例属性的使用
class Demo(object):

# 如果在构造方法内添加实例属性,可以保证每一个实例都拥有
def __init__(self, value):
self.value = value

# 一个实例方法,其中使用了 self 关键字添加实例属性
def add_value(self):
self.value1 = 0


# 创建一个实例(每个实例都有自己的属性)
demo1 = Demo(1000)
demo2 = Demo(2000)

# 输出两个实例中的所有元素
print(demo1.__dict__)
print(demo2.__dict__)

# 通过 self 以及实例名动态的添加属性
demo1.add_value()
demo2.value2 = 1000
print(demo1.__dict__)
print(demo2.__dict__)
1
2
3
4
5
6
7
8
9
10
11
12
# 定义一个空类,用于测试内部属性
class Demo(object):
pass

# 如果想看到一个类提供了哪些属性,就使用 dir
print(dir(Demo))

# 可以使用 help 查找某一个类的帮助信息
print(help(list))

# 可以通过内置的一些属性,输出想要的内容
print(Demo.__dict__)内置属性的查看

成员方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 在类内测试python提供的三种成员方法
class Demo(object):

# 实例方法: 第一个参数表示的是调用当前方法的实例,类似 this,通常名称为
# self,也可以换做其它名称(不推荐),通过 self 可以动态操作实例属性
def member_function(self):
print('member_function')

# 类方法: 第一个参数表示当前方法所在的类,类似类名,通常名称为 cls,类
# 方法常用于需要访问类属性但是不访问实例属性的情况
@classmethod
def class_function(cls):
print('class_function')

# 静态方法: 对方法名没有任何的要求,如果方法没有访问任何的属性,就可以设为静态的
@staticmethod
def static_method():
print('static_method')

属性限制

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 Demo(object):
# 仅双下划线开头表示这是私有的
__private_value = 1000

# __slots__ 可以限定我们能够创建什么样的属性
__slots__ = ('value1', 'value2')

# 通常双下划线开头表示私有,双下划线开头结尾表示解释器提供
# 单下划线开头约定俗称是私有的,但实际没有任何控制

# 通过 __dict__ 属性查看当前类内的所有类属性
print(Demo.__dict__)

# python 中的私有实际只是以一定的方式为属性修改了名称: _类名+属性名
print(Demo._Demo__private_value)

# 创建实例并使用实例动态添加属性
demo = Demo()
demo.value1 = 1000
demo.value2 = 1000
demo.value3 = 1000


class Demo2(object):
def __init__(self, name: int, age: int):
self._name = name
self._age = age

# 类魔术方法的重定义: __add__ __truediv__ __init__ __str__

类的继承

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
# 创建一个父类,提供了自己的属性和方法
class Parent(object):
# 父类提供的类属性
parent_value = 1000

# 构造方法,父类的构造方法
def __init__(self, name):
print(f'Parent.__init__({name})')


class Parent2(object):
parent_value = 2000

def __init__(self):
print(f'Parent2.__init__()')


# 创建一个子类,继承自 Parent
class Child(Parent, Parent2):

# 如果子类没有提供构造方法,就会使用父类的构造方法
def __init__(self):
print('Child.__init__()')
# 不会自动调用父类的构造方法
Parent.__init__(self, 'xiaoming')
# 使用 super 调用父类的构造方法
super().__init__('xiaoming')

# 如果对 super 进行传参,那么实际调用的将是参数
# 一在 mro(继承) 链中的下一个类的方法
Parent2.__init__(self)
super(Parent, self).__init__()
super(Child, self).__init__('xiaoming')


# 在子类中访问父类是属性
def visit_value(self):
# 直接以类名进行访问,访问父类的属性
print(Parent.parent_value)

child = Child()
child.visit_value()
print(Child.__mro__)


# object(1)
# parent1(3) parent2(2)
# child(parent1, parent2)(4)


# python 中继承的核心就是 mro

异常处理

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
try:
# 包含的是可能产生异常的语句
print(10 / 1)
except ZeroDivisionError:
# 如果产生了异常,就跳转到这个位置执行
print('产生了异常')
else:
# 正常情况下,所执行的代码
print('没有产生异常')


# 如果接收的异常类型和实际产生的不一致,就接收不了异常
try:
print(10 / 0)
except ZeroDivisionError: #NameError:
print('产生了名称异常')


# 在 python 中,产生任何一个异常都会抛出一个异常对象,
# 通过 except type as name 的方式可以接收到异常对象
try:
l = []
print(l[0])
# 接收到了 IndexError 异常对象并取名为 e
except IndexError as e:
print(e)


# 通常为了节省时间和精力会直接使用精简写法
try:
pass
# Exception 是通用异常(语法\网络\文件)的基类,通过这个类型
# 就可以接收到大多数的异常了
except Exception as e:
pass


import sys


# 通过 finally 可以保证程序无论以何种方式正常退出,其中的代码都被执行
# 例如这些语句: return continue break sys.exit(0)
try:
if True:
# sys.exit(0)
pass
finally:
# 用于执行清理操作
print('finally')


# 主动抛出异常,如果想要自定义异常,可以实现一个自己的继承自 BaseException 的异常类
# 然后通过 raise 主动的抛出这个类型,并进行处理
password = input('password: ')
if len(password) < 8:
raise Exception('密码长度过短')

文件操作

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
# 使用 Python 内置函数完成文件操作

# 参数一是文件所在的路径,参数二是打开方式,可能需要注意 encoding
file = open('content.txt', 'w+')

# 向文件的内部写入数据
file.write('hello 15pb')
file.writelines(['第一行\n', '第二行\n', '第三行\n'])

# 关闭文件,将对文件的修改保存到硬盘
file.close()

# 通过 with open() as name 的形式打开一个文件
with open('content.txt', 'r') as file:
# 将 open 函数的返回值保存到变量 file 中
# 对于文件对象,在离开 with 作用域的时候
# 会自动的进行关闭,只需要关注逻辑部分
print(file.read()) # 默认读取所有内容
print(file.readline()) # 一行最大字符个数
print(file.readlines()) # 读取的最多行数

# 以只读方式打开文件的时候,如果文件不存在就会产生异常
try:
with open('content2.txt') as file:
pass
except Exception as e:
print(e)

# 更多的函数: file.seek + file.tell -> 计算文件大小

# 文件操作模块: os,os 的使用方式和 C 语言的函数完全一致

内置函数和模块的使用

struct

1
2
3
4
5
6
7
8
9
10
# 通过 struct 可以实现字节流到结构体的转换
import struct

# 打包成 int + int + char[1024] 的结构体
bytes_content = struct.pack('ii1024s', 10, 20, b'hello15pb')
print(bytes_content)

# 将 nt + int + char[1024] 的结构体进行解包
type, length, content = struct.unpack('ii1024s', bytes_content)
print(type, length, content.decode('utf8').strip('\0'))

filter

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# filer: 将参数二指定的序列中,每一个元素都传入到参数一指定的函数中
# 如果该函数返回为 true,就将元素保存到一个新的序列中,否则丢弃

# 该函数最少需要有一个参数,用于接收序列中的每一个元素
def filer_function(letter):
# 如果是大写的,就保留,否则丢弃
return letter.isupper()


def filer_function2(value):
return True if value % 3 == 0 else False


print(list(filter(filer_function, 'AaBbCcDdEeFfGg')))
print(list(filter(filer_function2, range(1000))))

reduce

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import functools

# reduce: 第一个参数是一个函数,该函数一定要接收两个参数,在使用
# reduce 时,第一次会将可迭代对象红的元素一和元素二传入到函数中,
# 计算出一个返回值,接下来每次都将函数的返回结果和下一个元素进行
# 计算,知道序列遍历结束


def add_value(left, right):
return left + right

def mul_value(left, right):
return left * right


# 首先将 1 和 2 放入函数,返回 3,再将 3 和 3 计算返回 6,再将 6 和 4
# 计算返回 10,最终一直加到 10,返回的是 10 到 1 相加的和
print(functools.reduce(add_value, range(1, 11)))
print(functools.reduce(mul_value, range(1, 11)))

map

1
2
3
4
5
6
7
8
9
# map: 可以传入多个序列,参数一要求传入一个函数,函数接收的参数
# 个数必须和传入的序列个数相同,在使用 map 的时候,会分别将每
# 一个序列中的每一个元素传入函数,并且将函数的返回值组合成新
# 的序列

def function(left, right):
return left* right

print(list(map(function, 'abcdefg', [1, 2, 3, 4, 5, 6, 7])))

lambda

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# lambda 表达式的语法,表达式的结果是一个匿名函数
func = lambda letter, count: letter * count

# 1. 参数使用逗号隔开
# 2. 函数体使用冒号隔开
# 3. 函数体只能有一条语句
# 4. 函数体内的一条语句会被作为返回值
print(func('a', 10))


import functools


# 使用匿名函数可以在某些程度上,减少代码量
print(list(filter(lambda letter: letter.isupper(), "AaBbCcDdEeFfGg")))
print(functools.reduce(lambda left, right: left * right, range(1, 11)))
print(functools.reduce(lambda left, right: left + right, range(1, 11)))
print(list(map(lambda letter, count: letter * count, "abcdefg", [1, 2, 3, 4, 5, 6, 7])))

线程

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
# 使用 threading 可以实现线程操作(伪线程)
import threading
import time


# 不带参数的线程回调函数
def worker_thread():
for i in range(1000):
# current_thread 表示的始终都是当前的线程
print(threading.current_thread().name, i)
time.sleep(0.1)


# 模拟主函数的使用
def main():
# 通过 Thread 函数创建一个线程,需要指定起始位置(函数)
t = threading.Thread(target=worker_thread, name='worker_thread')
# Thread 创建的实际是线程对象,默认并没有运行,需要调用 start 函数
t.start()

for i in range(1000):
# current_thread 表示的始终都是当前的线程
print(threading.current_thread().name, i)
time.sleep(0.1)

# 通常,为了确保主线程退出之前,所有其它线程执行完毕,需要等待
t.join()


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
23
24
25
26
27
28
29
30
31
import threading


# 线程回调函数,带参
def thread1(arg1, arg2, arg3):
print(arg1, type(arg1))
print(arg2, type(arg2))
print(arg3, type(arg3))


# 线程回调函数,带元组变参
def thread2(*args):
print(args, type(args))


# 线程回调函数,带字典变参
def thread3(**kwargs):
print(kwargs, type(kwargs))


# 线程回调函数,带元组和字典变参
def thread4(*args, **kwargs):
print(args, type(args))
print(kwargs, type(kwargs))


# 创建多个线程,传递相应的参数
threading.Thread(target=thread2, args=(1, 2, 3)).start()
threading.Thread(target=thread3, kwargs={"a": 1, "b": 2, "c": 3}).start()
threading.Thread(target=thread4, args=(1, 2, 3), kwargs={"a": 1, "b": 2, "c": 3}).start()
threading.Thread(target=thread1, args=(1, 2, 3)).start()

线程的锁

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
# 使用 threading 可以实现线程操作(伪线程)
import threading
import time


# 定义一个全局的锁
lock = threading.Lock()


# 不带参数的线程回调函数
def worker_thread():
for i in range(1000):
lock.acquire()
# current_thread 表示的始终都是当前的线程
print(threading.current_thread().name, i)
time.sleep(0.1)
lock.release()


# 模拟主函数的使用
def main():
# 通过 Thread 函数创建一个线程,需要指定起始位置(函数)
t = threading.Thread(target=worker_thread, name='worker_thread')
# Thread 创建的实际是线程对象,默认并没有运行,需要调用 start 函数
t.start()

for i in range(1000):
lock.acquire()
# current_thread 表示的始终都是当前的线程
print(threading.current_thread().name, i)
time.sleep(0.1)
lock.release()

# 通常,为了确保主线程退出之前,所有其它线程执行完毕,需要等待
t.join()


if __name__ == '__main__':
main()

map与lambda结合实现杨辉三角

1
2
3
4
5
6
7
8
9
def generate(numRows):
if numRows==0:
return []
l1 = [[1]]
n = 1
while n<numRows:
l1.append(map(lambda x,y:x+y, [0]+l1[-1], l1[-1]+[0]))
n += 1
return l1

装饰器

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
# python 中高阶函数的定义: 参数或返回值为函数的函数就是高阶函数

# 闭包: 内部函数使用了外部函数的局部变量
def outer(left):
def inner(right):
return left * right
return inner


# 将做操作数传入给函数,实际上返回的是下列函数
"""
def inner(right):
return 10 * right
"""
inner = outer(10)

# 可以调用返回的函数,传入右操作数并得到结果
print(inner(20))


# 装饰器: 在闭包的基础上,使用了外部传入的函数
# 作用: 在不更改函数名称,参数个数和调用方式的前提下为某个函数添加新的功能

def w1(func):
def inner():
print('这里是新添加的内容')
func()
print('这里也是新添加的内容')
return inner

# @w1
# f1 是需要被装饰的函数
def f1():
print('f1')

f1()


# 装饰器实际上叫做语法糖,例如数组 arr[i][j] -> *(*(arr+i)+j)
"""
def 新的f1():
print('这里是新添加的内容')
f1() -> 旧的
print('这里也是新添加的内容')
"""
f1 = w1(f1) # @w1 def f1(): ....
f1()

time模块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import time

# 获取当前的时间戳(使用浮点数记录的秒数)
print(time.time())

# 将指定的时间戳转换为当前时区的元组
print(time.localtime())
print(time.gmtime()) # 标准时区

# 将时间元组转换为时间戳
print(time.mktime(time.localtime()))

# 睡眠一定的时间
time.sleep(0.500)

# 将时间元组转换成时间字符串
print(time.strftime("%Y-%m-%d %H:%M:%S",time.localtime()))

random模块

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
import random

# randint 和 randrange
for i in range(100):
# 生成 0<=value<=10 的一个随机数值
print(random.randint(0, 10))
# 先生成一个 range 序列,从中获取一个随机值
print(random.randrange(0, 10))

# 创建一个字符串,用于保存验证码
tmp = ""
# 主要在于遍历的次数,循环 6 次
for i in range(6):
# 生成一个满足 range 条件的随机值
rad1 = random.randrange(4)
# 有一半的概率进入下面的两个分支
if rad1 == 1 or rad1 == 3:
# 生成一个随机的整数并转换为字符串添加到末尾
rad2 = random.randrange(0, 10)
tmp += str(rad2)
else:
# 生成一个随机的大小字母添加到结尾
rad3 = random.randrange(65, 91)
tmp += chr(rad3)
print(tmp)


# 从指定序列中随机取出一个元素
print(random.choice(['饭', '粥', '面', '饿']))

# 打乱一个序列(洗牌)
l = [1, 2, 3, 4, 5, 6, 7]
random.shuffle(l)
print(l)

os模块

1
2
3
4
5
6
7
8
9
10
11
# os 模块提供了目录和文件能够执行的一些操作
import os

base = 'D:\\'

# 通过循环获取到指定目录下的所有文件和文件夹
for name in os.listdir(base):
# 判断目标名称是否为文件
if os.path.isfile(base+name):
# 输出文件名称以及后缀名
print(os.path.splitext(name))

网络编程

套接字

服务端

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
from socket import *


def main():
# 1. 创建套接字对象
server = socket(AF_INET, SOCK_STREAM)

# 2. 绑定对象到指定的ip和端口
server.bind(('127.0.0.1', 0x1515))

# 3. 开启套接字的监听状态
server.listen(SOMAXCONN)

# 4. 等待客户端的连接
client, address = server.accept()

# 5. 收发数据
client.send('welcome'.encode('utf-8'))

# 6. 关闭套接字
client.close()
server.close()


if __name__ == '__main__':
main()

客户端

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


def main():
# 1. 创建套接字对象
client = socket(AF_INET, SOCK_STREAM)

# 2. 等待客户端的连接
client.connect(('127.0.0.1', 0x1515))

# 3. 收发数据
print(client.recv(100).decode('utf-8'))

# 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
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
from socket import *
from struct import *
from threading import *
Mysql = __import__('数据库操作')#源码就在下一个节点


# 提供一个列表保存所有的在线用户
clients = {}

# 创建一个数据库对象,连接到 chatroom
mysql = Mysql.Mysql('chatroom')


# 线程回调函数: 接收来自另一边的信息
def reciver(sock):
# 接收目标发送过来的用户名和密码 char[32] + char[32]
username, password = unpack('32s32s', sock.recv(64))
username = username.decode('utf-8').strip('\0')
password = password.decode('utf-8').strip('\0')

# 查询目标用户名和密码是否匹配
count, result = mysql.select(f"SELECT * FROM user WHERE username='{username}' AND password=MD5('{password}');")

# 如果登录成功,就添加到在线列表
if count == 0:
sock.send('不ok'.encode())
return

if username in clients:
sock.send('不ok'.encode())
return
else:
sock.send('ok'.encode())
clients[username] = sock
print(sock.getpeername(), '连接到了聊天室')

while True:
try:
# 接收客户端发送的数据,由于只是转发,不做解码
content = sock.recv(100)
# 遍历在线用户,如果不是发送者就转发
for client in clients.values():
if client != sock:
client.send(username.encode() + b': ' + content)
except Exception as e:
# print('error', e)
# 客户端或服务器连接中断,需要从列表中移除
print(sock.getpeername(), '离开了聊天室')
del clients[username]
# 一定要记得 break 跳出当前的循环
break


def main():
# 1. 创建套接字对象
server = socket(AF_INET, SOCK_STREAM)

# 2. 绑定对象到指定的ip和端口
server.bind(('127.0.0.1', 0x1515))

# 3. 开启套接字的监听状态
server.listen(SOMAXCONN)

while True:
# 4. 等待客户端的连接
client, address = server.accept()

# 5. 收发数据
Thread(target=reciver, args=(client,)).start()


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
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
from socket import *
from struct import *
from threading import *


# 线程回调函数: 接收来自另一边的信息
def reciver(sock):
while True:
try:
# 如果客户端或服务器断开连接,会产生异常
print(sock.recv(100).decode('utf-8'))
except Exception as e:
print('error', e)
# 一定要记得 break 跳出当前的循环
break


def main():
# 1. 创建套接字对象
client = socket(AF_INET, SOCK_STREAM)

# 2. 等待客户端的连接
client.connect(('127.0.0.1', 0x1515))

# 填写用户名和密码尝试进行登录
username = input('username: ')
password = input('password: ')
content = pack('32s32s', username.encode(), password.encode())
client.send(content)

# 接收登录的结果,如果失败,就退出
if client.recv(100).decode() == '不ok':
return
print('xxxxxxx')

# 3. 收发数据
Thread(target=reciver, args=(client, )).start()
while True:
content = input('')
if content == 'quit':
break
else:
client.send(content.encode())

# 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
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# 通过 pymysql 连接并操作 mysql 数据库
import pymysql


class Mysql(object):

def __init__(self, database_name):
try:
# 通过 connect 函数传入数据库的配置信息连接到数据库
self.connect = pymysql.connect(host='127.0.0.1', user='root', password='123456', port=3306, database=database_name)
# 一旦数据库连接成功,我们就需要获取到游标对象
self.cursor = self.connect.cursor()#获取操作游标
except Exception as e:
print('error', e)

def insert(self, sql: str):
try:
# execute执行sql语句
self.cursor.execute(sql)
# 对于所有修改数据库的操作,都需要提交
self.connect.commit()
except Exception as e:
#回滚操作
self.connect.rollback()
print('error', e)

def select(self, sql: str):
try:
self.cursor.execute(sql)
# 从数据库中获取到查询的结果集,返回的是一个元组,
# 元组中的每一个元素表示一行,保存的是一行中的每一列
result = self.cursor.fetchall()/#获取所有内容
count = self.cursor.rowcount/#获取行数
# 将查询到的行数和内容进行打包,返回给调用方
return count, result
except Exception as e:
print('error', e)


if __name__ == '__main__':
sql = Mysql('student')
sql.insert("INSERT INTO stu_class VALUE(10, 'ten')")
print(sql.select('select * from stu_class;'))

小功能实现

阶乘

1
2
3
4
5
6
7
8
9
10
11
12
def Get_Num(Num):
j = 0
for b in range(1, Num+1):
i = 1
for c in range(1, b+1):
i *=c
#print(i)
j += i
return j

print(Get_Num(5))

水仙花数

1
2
3
4
5
6
7
8
'''水仙花数'''

Num = 100

while Num < 1000:
if Num == (Num//100 % 10) **3 + (Num//10 % 10) **3 + (Num//1 % 10)**3:
print(Num)
Num +=1

三角图形

1
2
3
4
5
6
打印如下图形

*
***
*****
*******

方法1

1
2
for i in range(4):
print(" "*(4-i),"*"*(2*i+1))

方法2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
num = 1
num2 = 4
num3 = 4
while num <= 4:
num1 = 1
while num1 <= 7:
if num1 >= num2 and num1 <=num3:
print('*', end='')
else:
print(' ', end='')
num1 += 1
num2 -= 1
num3 += 1
print('')
num += 1

菱形

1
2
3
4
5
6
7
8
打印如下图型
*
***
*****
*******
*****
***
*
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
num = 1
num2 = 4
num3 = 4
while num <= 7:
num1 = 1
while num1 <= 7:
if num1 >= num2 and num1 <=num3:
print('*', end='')
else:
print(' ', end='')
num1 += 1
if num < 4:
num2 -= 1
num3 += 1
else:
num2 += 1
num3 -= 1
print('')
num += 1

空菱形

1
2
3
4
5
6
7
8
   打印如下图型
*
* *
* *
* *
* *
* *
*
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
num = 1
num2 = 4
num3 = 4
while num <= 7:
num1 = 1
while num1 <= 7:
if num1 == num2 or num1 ==num3:
print('*', end='')
else:
print(' ', end='')
num1 += 1
if num < 4:
num2 -= 1
num3 += 1
else:
num2 += 1
num3 -= 1
print('')
num += 1

冒泡排序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'''冒泡排序'''
List = [20, 30, 40, 3, 6, 47, 25, 77, 15]

Num = 0
temp = 0
lenth = len(List) - 1
while Num <= lenth-1:
for i in range(len(List)):
if i < lenth:
if List[i] > List[i+1]:
temp = List[i]
List[i] = List[i+1]
List[i+1] = temp
Num += 1
print(List)

杨辉三角

方法1

1
2
3
4
5
6
7
8
9
def generate(numRows):
if numRows==0:
return []
l1 = [[1]]
n = 1
while n<numRows:
l1.append(map(lambda x,y:x+y, [0]+l1[-1], l1[-1]+[0]))
n += 1
return l1

方法2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#杨辉三角
def generate(numRows):
if numRows==0:
return []
if numRows==1:
return[[1]]
if numRows==2:
return [[1],[1,1]]
numRows -= 2
rList = [[1],[1,1]]
while numRows>0:
newList = [1]
for i in range(len(rList[-1])-1):
newList.append(rList[-1][i]+rList[-1][i+1])
newList.append(1)
rList.append(newList)
numRows -= 1
return rList

方法3

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def Yhsj(row):
result = [1]
n = 0
while n < row:
if n < 1:
yield result
else:
a = 1
t = tuple(x for x in result)
result = [1, 1]
while a < n:
result.insert(a, t[a - 1] + t[a])
a += 1
yield result
n += 1

方法4

1
2
3
4
5
6
7
8
9
10
11
12
13
def generate(self, numRows):
"""
:type numRows: int
:rtype: List[List[int]]
"""
l1 = [1]
l2 = []
n = 0
while n<numRows:
l2.append(l1)
l1 = [sum(t) for t in zip([0]+l1, l1+[0])]
n += 1
return l2

方法5

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
def generate(self, numRows):
"""
:type numRows: int
:rtype: List[List[int]]
"""
if numRows==0:
return []
if numRows==1:
return[[1]]
if numRows==2:
return [[1],[1,1]]
numRows -= 2
rList = [[1],[1,1]]
while numRows>0:
newList = [1]
for i in range(len(rList[-1])-1):
newList.append(rList[-1][i]+rList[-1][i+1])
newList.append(1)
rList.append(newList)
numRows -= 1
return rList

方法6

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def Yanghui():
n = [1]
while True:
yield n
n.append(0)
n = [n[i] + n[i-1] for i in range(len(n))]

def fun(n):
for i in Yanghui():
print(i)
n -= 1
if n == 0:
break



fun(10)