数据类型

Python 默认拥有以下内置数据类型:

文本类型: str
数值类型: int, float, complex
序列类型: list, tuple, range
映射类型: dict
集合类型: set, frozenset
布尔类型: bool
二进制类型: bytes, bytearray, memoryview

在 Python 中,当您为变量赋值时,会设置数据类型:

示例 数据类型
x = "Hello World" str
x = 29 int
x = 29.5 float
x = 1j complex
x = ["apple", "banana", "cherry"] list
x = ("apple", "banana", "cherry") tuple
x = range(6) range
x = {"name" : "Bill", "age" : 63} dict
x = {"apple", "banana", "cherry"} set
x = frozenset({"apple", "banana", "cherry"}) frozenset
x = True bool
x = b"Hello" bytes
x = bytearray(5) bytearray
x = memoryview(bytes(5)) memoryview

如果希望指定数据类型,则您可以使用以下构造函数:

示例 数据类型
x = str("Hello World") str
x = int(29) int
x = float(29.5) float
x = complex(1j) complex
x = list(("apple", "banana", "cherry")) list
x = tuple(("apple", "banana", "cherry")) tuple
x = range(6) range
x = dict(name="Bill", age=36) dict
x = set(("apple", "banana", "cherry")) set
x = frozenset(("apple", "banana", "cherry")) frozenset
x = bool(5) bool
x = bytes(5) bytes
x = bytearray(5) bytearray
x = memoryview(bytes(5)) memoryview

文件

open函数的参数

要读写文件,首先要通过内置函数open 打开文件,获得文件对象。

函数open的参数如下

open(
file,
mode='r',
buffering=-1,
encoding=None,
errors=None,
newline=None,
closefd=True,
opener=None
)

其中下面这3个参数是我们常用的。

  • 参数 file

    file参数指定了要打开文件的路径。

    可以是相对路径,比如 ‘log.txt’, 就是指当前工作目录下面的log.txt 文件,
    也可以是绝对路径,比如 ’d:\project\log\log.txt',
  • 参数 mode

    mode参数指定了文件打开的 模式 ,打开文件的模式,决定了可以怎样操作文件。

    常用的打开模式有

    • r 只读文本模式打开,这是最常用的一种模式
    • w 只写文本模式打开
    • a 追加文本模式打开

    如果我们要 读取文本文件内容到字符串对象中 , 就应该使用 r 模式。

    我们可以发现mode参数的缺省值 就是 ‘r’ 。

    就是说,调用open函数时,如果没有指定参数mode的值,那么该参数就使用缺省值 ‘r’,表示只读打开。

    如果我们要 创建一个新文件写入内容,或者清空某个文本文件重新写入内容, 就应该使用 ‘w’ 模式。

    如果我们要 从某个文件末尾添加内容, 就应该使用 ‘a’ 模式。

  • 参数 encoding

    encoding 参数指定了读写文本文件时,使用的 字符编解码 方式。

    调用open函数时,如果传入了encoding参数值:

      后面调用write写入字符串到文件中,open函数会使用指定encoding编码为字节串;
    
      后面调用read从文件中读取内容,open函数会使用指定encoding解码为字符串对象

    如果调用的时候没有传入encoding参数值,open函数会使用系统缺省字符编码方式。 比如在中文的Windows系统上,就是使用cp936(就是gbk编码)。

    建议大家编写代码 读写文本文件时,都指定该参数的值。

if __name__ == '__main__':
# 指定编码方式为 utf8
f = open('D:/Code2022/Python/pythonProjectStudy/table_contents/tmp.txt', 'w', encoding='utf8') # write方法会将字符串编码为utf8字节串写入文件
f.write('李嘉图:祝大家学有所成!') # 文件操作完毕后, 使用close 方法关闭该文件对象
f.close()
# 指定编码方式为utf8
f = open('D:/Code2022/Python/pythonProjectStudy/table_contents/tmp.txt', 'r', encoding='utf8') # read 方法会在读取文件中的原始字节串后, 根据上面指定的gbk解码为字符串对象返回
content = f.read() # 文件操作完毕后, 使用close 方法关闭该文件对象
f.close() # 通过字符串的split方法获取其中用户名部分
name = content.split(':')[0] print(name)

with

if __name__ == '__main__':
f = open('D:/Code2022/Python/pythonProjectStudy/table_contents/tmp.txt', 'w', encoding='utf8')
f.write('李嘉图:祝大家学有所成!')
f.close() with open('D:/Code2022/Python/pythonProjectStudy/table_contents/tmp.txt', 'r', encoding='utf8') as f:
linelist = f.readlines()
for line in linelist:
print(line)

附加:文件和目录

https://www.byhy.net/tut/py/extra/file_dir/

自调用其他程序

Python中调用外部程序主要是通过两个方法实现的, 一个是os库的 system 函数,另外一个是 subprocess 库。

os.system函数

使用os库的 system 函数 调用其它程序 是非常方便的。就把命令行内容 作为 system 函数的参数 即可

import os

if __name__ == '__main__':
os.system('cd D:/test && mkdir test.txt')

os.system 函数调用外部程序的时候, 必须要等被调用程序执行结束, 才会接着往下执行代码。 否则就会一直等待

os.system 函数没法获取 被调用程序输出到终端窗口的内容。 如果需要对被调用程序的输出信息进行处理的话, 可以使用 subprocess 模块。

os.startfile 函数

如果我们想达到类似文件浏览器双击打开一个文件的效果可以使用 os.startfile 函数。

这个函数的参数可以是任何 非可执行程序 文件

os.startfile('d:\\统计数据.xlsx')

可以调用该xlsx对应的关联程序(Excel)来打开该文件。

subprocess 模块

Popen 是 subprocess的核心,子进程的创建和管理都靠它处理。

线程和进程

创建新线程

# 从 threading 库中导入Thread类
from threading import Thread
from time import sleep # 定义一个函数,作为新线程执行的入口函数
def threadFunc(arg1, arg2):
print('子线程 开始')
print(f'线程函数参数是:{arg1}, {arg2}')
sleep(5)
print('子线程 结束') if __name__ == '__main__':
print('主线程执行代码') # 创建 Thread 类的实例对象
thread = Thread(
# target 参数 指定 新线程要执行的函数
# 注意,这里指定的函数对象只能写一个名字,不能后面加括号,
# 如果加括号就是直接在当前线程调用执行,而不是在新线程中执行了
target=threadFunc, # 如果 新线程函数需要参数,在 args里面填入参数
# 注意参数是元组, 如果只有一个参数,后面要有逗号,像这样 args=('参数1',)
args=('参数1', '参数2')
) # 执行start 方法,就会创建新线程,
# 并且新线程会去执行入口函数里面的代码。
# 这时候 这个进程 有两个线程了。
thread.start() # 主线程的代码执行 子线程对象的join方法,
# 就会等待子线程结束,才继续执行下面的代码
thread.join()
print('主线程结束')

共享数据的访问控制

from threading import Thread, Lock
from time import sleep bank = {
'count': 0
} bankLock = Lock() # 定义一个函数,作为新线程执行的入口函数
def deposit(theadidx, amount):
# 操作共享数据前,申请获取锁
bankLock.acquire() balance = bank['count']
# 执行一些任务,耗费了0.1秒
sleep(0.1)
bank['count'] = balance + amount
print(f'子线程 {theadidx} 结束') # 操作完共享数据后,申请释放锁
bankLock.release() if __name__ == '__main__':
theadlist = []
for idx in range(10):
thread = Thread(target=deposit,
args=(idx, 1)
)
thread.start()
# 把线程对象都存储到 threadlist中
theadlist.append(thread)
for thread in theadlist:
thread.join() print('主线程结束')
print(f'最后我们的账号余额为 {bank["count"]}')

deamon线程

from threading import Thread
from time import sleep def threadFunc():
sleep(1)
print('子线程 结束') if __name__ == '__main__':
# thread = Thread(target=threadFunc)
# thread.start()
# print('主线程结束')
thread = Thread(target=threadFunc,
daemon=True # 设置新线程为daemon线程
)
thread.start()
print('daemon主线程结束')

多线程

Python 官方解释器 的每个线程要获得执行权限,必须获取一个叫 GIL (全局解释器锁) 的东西。

这就导致了 Python 的多个线程 其实 并不能同时使用 多个CPU核心。

所以如果是计算密集型的任务,不能采用多线程的方式。

from threading import Thread

def f():
while True:
b = 53*53 if __name__ == '__main__':
plist = []
# 启动10个线程
for i in range(10):
p = Thread(target=f)
p.start()
plist.append(p) for p in plist:
p.join()

多个CPU核心的运算能力,可以使用Python的多进程库。

from multiprocessing import Process

def f():
while True:
b = 53*53 if __name__ == '__main__':
plist = []
for i in range(2):
p = Process(target=f)
p.start()
plist.append(p) for p in plist:
p.join()
from multiprocessing import Process, Manager
from time import sleep def f(taskno, return_dict):
sleep(1)
# 存放计算结果到共享对象中
return_dict[taskno] = taskno if __name__ == '__main__':
manager = Manager()
# 创建 类似字典的 跨进程 共享对象
return_dict = manager.dict()
plist = []
for i in range(10):
p = Process(target=f, args=(i, return_dict))
p.start()
plist.append(p)
for p in plist:
p.join()
print('get result...')
# 从共享对象中取出其他进程的计算结果
for k, v in return_dict.items():
print(k, v)

JSON

序列化和反序列化

Python中内置了json这个库,可以 方便的把内置的数据对象 序列化为json格式文本的字符串。

import json

historyTransactions = [

    {
'time': '20300101070311', # 交易时间
'amount': '3088', # 交易金额
'productid': '45454455555', # 货号
'productname': 'iphone30' # 货名
},
{
'time': '20300101050311', # 交易时间
'amount': '18', # 交易金额
'productid': '453455772955', # 货号
'productname': '饼干' # 货名
} ] if __name__ == '__main__':
# dumps 方法将数据对象序列化为 json格式的字符串
jsonstr = json.dumps(historyTransactions)
print(jsonstr)
import json

historyTransactions = [

    {
'time': '20300101070311', # 交易时间
'amount': '3088', # 交易金额
'productid': '45454455555', # 货号
'productname': 'iphone30' # 货名
},
{
'time': '20300101050311', # 交易时间
'amount': '18', # 交易金额
'productid': '453455772955', # 货号
'productname': '饼干' # 货名
} ] if __name__ == '__main__':
# dumps 方法将数据对象序列化为 json格式的字符串
jsonstr = json.dumps(historyTransactions)
print(jsonstr)
print('================')
print(json.dumps(historyTransactions, ensure_ascii=False, indent=4))
print('================')
jsonstr = '[{"time": "20300101070311", "amount": "3088", "productid": "45454455555", "productname": "iphone7"}, {"time": "20300101070311", "amount": "18", "productid": "453455772955", "productname": "\u5999\u5999\u5999"}]'
translist = json.loads(jsonstr)
print(translist)
print(type(translist))

装饰器

Python中装饰器通常用来装饰函数、或者类的方法。

通常被装饰后的函数, 会在原有的函数基础上,增加一点功能。

装饰器经常被用在库和框架中, 给别的开发者使用。

这些库的开发者预料到 使用者 开发的函数可能需要 一些增强的功能。

但是 这些库的开发者 没法去改使用者的代码, 就可以把这些增强的部分做在 装饰器函数中。

这样使用者,只需要在他们的函数前面上@xxx 就使用了这些增强的功能了。

基础示例:

import time

# 定义一个装饰器函数
def sayLocal(func):
def wrapper():
curTime = func()
return f'当地时间: {curTime}' return wrapper @sayLocal
def getXXXTime():
print()
return time.strftime('%Y_%m_%d %H:%M:%S', time.localtime()) if __name__ == '__main__':
# 装饰 getXXXTime
# getXXXTime = sayLocal(getXXXTime)
print(getXXXTime())

进阶示例-被装饰的函数有参数:

import time

def sayLocal(func):
def wrapper(*args, **kargs):
curTime = func(*args, **kargs)
return f'当地时间: {curTime}' return wrapper @sayLocal
def getXXXTimeFormat1(name):
curTime = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())
return f'{curTime} ,数据采集者:{name} ' @sayLocal
def getXXXTimeFormat2(name, place):
curTime = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())
return f'{curTime} ,数据采集者:{name} , 采集地:{place}' if __name__ == '__main__':
print(getXXXTimeFormat1('张三'))
print(getXXXTimeFormat2('张三', place='北京'))

进阶示例-装饰器函数自身有参数:

# 添加输出日志的功能
def logging(flag):
def decorator(fn):
def inner(num1, num2):
if flag == "+":
print("--正在努力加法计算--")
elif flag == "-":
print("--正在努力减法计算--")
result = fn(num1, num2)
return result return inner # 返回装饰器
return decorator # 使用装饰器装饰函数
@logging("+")
def add(a, b):
result = a + b
return result @logging("-")
def sub(a, b):
result = a - b
return result if __name__ == '__main__':
result = add(1, 2)
print(result) result = sub(1, 2)
print(result)

加密

算法 计算结果长度
MD5 16字节
SHA1 20字节
SHA224 28字节
SHA256 32字节
SHA384 48字节
SHA512 64字节

典型应用场景:

校验拷贝下载文件

校验信息有效性

使用 Python 内置库 hashlib 创建hash值。

示例:

import hashlib

if __name__ == '__main__':
# 使用 md5 算法
# m = hashlib.md5()
# 如果你想使用别的哈希算法,比如, sha256 算法,只需要修改为对应的函数 sha256()即可
m = hashlib.sha256() # 要计算的源数据必须是字节串格式
# 字符串对象需要encode转化为字节串对象
m.update("ML李嘉图|mllijaitu".encode()) # 产生哈希值对应的bytes对象
resultBytes = m.digest()
# 产生哈希值的十六进制表示
resultHex = m.hexdigest()
print(resultHex)

SSH远程操作

Python第三方库 Paramiko 就是作为ssh客户端远程控制Linux主机 的。

exec_command 是每次执行都是 新打开一个channel的东西执行,

每个channel都是命令执行的环境,每执行命令都是一个新的执行环境,不在上次执行的环境里面,

相当于 每次都在各自的执行环境里面,和前面的执行环境没有关系。

多个命令一起执行,用分号隔开,像这样:

stdin, stdout, stderr = ssh.exec_command("cd testdir;pwd")

操作单台主机:

# 单台主机操作
import paramiko #############################配置信息#####################################
# 登陆参数设置
hostname = ""
host_port = 22
username = "root"
password = "" ######################################################################## def ssh_client_con():
"""创建ssh连接,并执行shell指令"""
# 1 创建ssh_client实例
ssh_client = paramiko.SSHClient()
# 自动处理第一次连接的yes或者no的问题
ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy)
# 2 连接服务器
ssh_client.connect(
port=host_port,
hostname=hostname,
username=username,
password=password
)
# 3 执行shell命令
# 构造shell指令
shell_command = "ls"
stdin, stdout, stderr = ssh_client.exec_command(shell_command)
# 输出返回信息
stdout_info = stdout.read().decode('utf8')
print(stdout_info)
# 输出返回的错误信息
stderr_info = stderr.read().decode('utf8')
print(stderr_info) def sftp_client_con():
# 1 创建transport通道
tran = paramiko.Transport((hostname, host_port))
tran.connect(username=username, password=password)
# 2 创建sftp实例
sftp = paramiko.SFTPClient.from_transport(tran)
# 3 执行上传功能
local_path = "" # 本地路径
remote_path = "" # 远程路径
put_info = sftp.put(local_path, remote_path, confirm=True)
print(put_info)
print(f"上传{local_path}完成")
# 4 执行下载功能
save_path = "" # 本地保存文件路径
sftp.get(remotepath=remote_path, localpath=save_path)
print(f'下载{save_path}完成')
# 5 关闭通道
tran.close() if __name__ == '__main__':
# 调用函数执行功能
ssh_client_con()
# sftp_client_con()

Python面向对象编程

类变量与实例变量

# 创建一个学生类
class Student:
# number属于类变量,不属于某个具体的学生实例
number = 0 # 定义学生属性,初始化方法
# name和score属于实例变量
def __init__(self, name, score):
self.name = name
self.score = score
Student.number = Student.number + 1 # 定义打印学生信息的方法
def show(self):
print("Name: {}. Score: {}".format(self.name, self.score)) # 实例化,创建对象
student1 = Student("John", 100)
student2 = Student("Lucy", 99) print(Student.number) # 打印2
print(student1.__class__.number) # 打印2

类方法

有些变量只属于类,有些方法也只属于类,不属于具体的对象。

你有没有注意到属于对象的方法里面都有一个self参数, 比如__init__(self), show(self)?

self是指对象本身。

属于类的方法不使用self参数, 而使用参数cls,代表类本身。

另外习惯上对类方法我们会加上@classmethod的修饰符做说明。

class Student:
# number属于类变量,不属于某个具体的学生实例
number = 0 # 定义学生属性,初始化方法
# name和score属于实例变量
def __init__(self, name, score):
self.name = name
self.score = score
Student.number = Student.number + 1 # 定义打印学生信息的方法
def show(self):
print("Name: {}. Score: {}".format(self.name, self.score)) # 定义类方法,打印学生的数量
@classmethod
def total(cls):
print("Total: {0}".format(cls.number)) if __name__ == '__main__':
# 实例化,创建对象
student1 = Student("John", 100)
student2 = Student("Lucy", 99) Student.total() # 打印 Total: 2

类的私有属性和私有方法

类里面的私有属性和私有方法以双下划线__开头。私有属性或方法不能在类的外部被使用或直接访问。

# 创建一个学生类
class Student: # 定义学生属性,初始化方法
# name和score属于实例变量, 其中__score属于私有变量
def __init__(self, name, score):
self.name = name
self.__score = score # 定义打印学生信息的方法
def show(self):
print("Name: {}. Score: {}".format(self.name, self.__score)) # 实例化,创建对象
student1 = Student("John", 100) student1.show() # 打印 Name: John, Score: 100
student1.__score # 打印出错,该属性不能从外部访问。

@property

# 创建一个学生类
class Student: # 定义学生属性,初始化方法
# name和score属于实例变量, 其中score属于私有变量
def __init__(self, name, score):
self.name = name
self.__score = score # 利用property装饰器把函数伪装成属性
@property
def score(self):
print("Name: {}. Score: {}".format(self.name, self.__score)) if __name__ == '__main__':
# 实例化,创建对象 student1 = Student("John", 100) student1.score # 打印 Name: John. Score: 100

类的继承

# 创建父类学校成员SchoolMember
class SchoolMember: def __init__(self, name, age):
self.name = name
self.age = age def tell(self):
# 打印个人信息
print('Name:"{}" Age:"{}"'.format(self.name, self.age), end=" ") # 创建子类老师 Teacher
class Teacher(SchoolMember): def __init__(self, name, age, salary):
SchoolMember.__init__(self, name, age) # 利用父类进行初始化
self.salary = salary # 方法重写
def tell(self):
SchoolMember.tell(self)
print('Salary: {}'.format(self.salary)) # 创建子类学生Student
class Student(SchoolMember): def __init__(self, name, age, score):
SchoolMember.__init__(self, name, age)
self.score = score def tell(self):
SchoolMember.tell(self)
print('score: {}'.format(self.score)) if __name__ == '__main__':
teacher1 = Teacher("John", 44, "$60000")
student1 = Student("Mary", 12, 99)
teacher1.tell()
student1.tell()

静态变量和静态方法

# 创建一个学生类
class Student:
# number属于类变量,定义在方法外,不属于具体实例
number = 0 # 定义学生属性,初始化方法
# name和score属于实例变量,定义在方法里
def __init__(self, name, score):
self.name = name
self.score = score
Student.number = self.number + 1 # 定义打印学生信息的方法
def show(self):
print("Name: {}. Score: {}".format(self.name, self.score)) # 静态方法无法使用cls和self参数访问类或实例的变量
@staticmethod
def func1():
print("this is static function!")

Python-基础学习-第二轮的更多相关文章

  1. python基础学习——第二天

    一.python种类 1.1 Cpython python官方版本,使用c语言实现,运行机制:先编译,py(源码文件)->pyc(字节码文件),最终执行时先将字节码转换成机器码,然后交给cpu执 ...

  2. python基础学习第二天

    读文件 r 要以读文件的模式打开一个文件对象,使用Python内置的open()函数,传入文件名和标示符 写文件 w 写文件和读文件是一样的,唯一区别是调用open()函数时,传入标识符’w’或者’w ...

  3. Day1 Python基础学习

    一.编程语言分类 1.简介 机器语言:站在计算机的角度,说计算机能听懂的语言,那就是直接用二进制编程,直接操作硬件 汇编语言:站在计算机的角度,简写的英文标识符取代二进制去编写程序,本质仍然是直接操作 ...

  4. Day1 Python基础学习——概述、基本数据类型、流程控制

    一.Python基础学习 一.编程语言分类 1.简介 机器语言:站在计算机的角度,说计算机能听懂的语言,那就是直接用二进制编程,直接操作硬件 汇编语言:站在计算机的角度,简写的英文标识符取代二进制去编 ...

  5. Python基础学习二

    Python基础学习二 1.编码 utf-8编码:自动将英文保存为1个字符,中文3个字符.ASCll编码被囊括在内. unicode:将所有字符保存为2给字符,容纳了世界上所有的编码. 2.字符串内置 ...

  6. Python基础学习五

    Python基础学习五 迭代 for x in 变量: 其中变量可以是字符串.列表.字典.集合. 当迭代字典时,通过字典的内置函数value()可以迭代出值:通过字典的内置函数items()可以迭代出 ...

  7. python基础学习8

    python基础学习8 内容概要 字典的内置方法 元组的内置方法 集合的内置方法 垃圾回收机制 内容详情 字典的内置方法 一.类型转换 res = dict(name='jason', pwd=123 ...

  8. 0003.5-20180422-自动化第四章-python基础学习笔记--脚本

    0003.5-20180422-自动化第四章-python基础学习笔记--脚本 1-shopping """ v = [ {"name": " ...

  9. Python 基础学习 总结篇

    Python 基础学习总结 先附上所有的章节: Python学习(一)安装.环境配置及IDE推荐 Python学习(二)Python 简介 Python学习(三)流程控制 Python学习(四)数据结 ...

  10. (一)python基础学习

    根据廖雪峰老师的python教程写一些学习总结! Python基础学习 1.使用list和tuple (1)list Python内置的一种数据类型是列表:list.list是一种有序的集合,可以随时 ...

随机推荐

  1. 个人冲刺(四阶段)——体温上报app(一阶段)

    任务:完成了后台数据库的类模块 MyDBHelper.java package com.example.helloworld; import android.content.Context; impo ...

  2. python之部分内置函数与迭代器与异常处理

    目录 常见内置函数(部分) 可迭代对象 迭代器对象 for循环内部原理 异常处理 异常信息的组成部分 异常的分类 异常处理实操 异常处理的其他操作 for循环本质 迭代取值与索引取值的区别 常见内置函 ...

  3. Java开发学习(二)----IOC、DI入门案例

    一.IOC入门案例 1.1 思路分析 (1)Spring是使用容器来管理bean对象的,那么管什么? 主要管理项目中所使用到的类对象,比如(Service和Dao) (2)如何将被管理的对象告知IOC ...

  4. Vben Admin 源码学习:状态管理-错误日志

    0x00 前言 本文将对 Vue-Vben-Admin 的状态管理实现源码进行分析解读,耐心读完,相信您一定会有所收获! 0x01 errorLog.ts 错误日志 文件 src\store\modu ...

  5. 盘点微信小程序跨页面传值的若干方式

    直接给大家上干货 1.跳转页面传递参数 pageA.wxml <button type="primary" bindtap="jumpTo">点击跳 ...

  6. 并发编程原理学习:synchronized关键字

    概述 关键字synchronized可以修饰方法或者以同步代码块的形式来进行使用,它主要确保多个线程在同一时刻只能有一个线程处于方法或者同步块中,它保证了线程对变量访问的可见性和排他性. 同步代码块 ...

  7. 设置C#启动进程但不显示命令行窗口

    设置一下Process类型相关的配置属性即可,直接上代码. //记得引入命名空间 //using System.Diagnostics; //获得当前环境的基路径 string basePath = ...

  8. Windows-VS2017创建.NET项目

    首先新建->项目 选择如下, 注意要选择.NET Framework4.x 选择对应的项目类型 建议选上Web窗体(如果是用于实验的话) 完成后进行测试 如果出现 HTTP Error 403. ...

  9. UiPath保存图片操作的介绍和使用

    一.保存图像 (Save Image)的介绍 可以将图像保存到磁盘的一种活动 二.保存图像 (Save Image)在UiPath中的使用 1. 打开设计器,在设计库中新建一个Sequence,为序列 ...

  10. git 删除、合并多次commit提交记录

    合并多次记录 1. git log找到要合并的记录的数量. 2. git rebase -i HEAD~5 将最上面一个的记录选为pack,下面记录都改为s. ================= 删除 ...