Python的输出打印有四种方式,分别通过字符串格式化符号
、str.format()格式化字符串
、f-string格式化字符串
、以及直接打印逗号分隔
。
其中常用的字符串格式化符号如下:
格式符号 | 转换 |
---|---|
%s | 字符串 |
%d | 有符号的十进制整数 |
%f | 浮点数 |
%c | 字符 |
%u | 无符号十进制整数 |
%o | 八进制整数 |
%x | 十六进制整数(小写ox) |
%X | 十六进制整数(大写OX) |
%e | 科学计数法(小写’e’) |
%E | 科学计数法(大写’E’) |
%g | %f和%e的简写 |
%G | %f和%E的简写 |
技巧
- %06d,表示输出的整数显示位数,不足以0补全,超出当前位数则原样输出
- %.2f,表示小数点后显示的小数位数。
age = 18
name = 'TOM'
weight = 75.5321313
# 我的名字是TOM,明年019岁了, 体重75.53公斤
print('我的名字是%s,明年%03d岁了, 体重%.2f公斤' % (name, age + 1, weight))
# 我的名字是TOM,明年019岁了, 体重75.53公斤
print('我的名字是{0:s}, 明年{1:03d}岁了, 体重{2:.2f}公斤'.format(name, age + 1, weight))
# 我的名字是TOM,明年019岁了, 体重75.53公斤
print(f'我的名字是{
name}, 明年{
age + 1:03d}岁了, 体重{
weight:.2f}公斤')
# 我的名字是TOM, 明年19岁了, 体重75.5321313公斤
print('我的名字是', name, ', 明年', age+1, '岁了, 体重', weight, '公斤', sep='')
注意:
f-string
是目前效率最高的格式化打印字符串实现方法,详细的格式化方法可以参考博文Python 中 str.format() 方法详解。
输入功能的实现很简单,实现方法用一句话可以实现:input('提示文字')
,input接收的任何数据默认都是字符串数据类型,需要自己判断后自行转换。
password = input('请输入您的密码:')
print(f'您输入的密码是:{
password}')
与C++的数据转换相仿,常用的数据类型转换函数表如下:
函数 | 说明 |
---|---|
int(x [,base ]) | 将x转换为一个整数 |
float(x) | 将x转换为一个浮点数 |
complex(real [,imag ]) | 创建一个复数,real为实部,imag为虚部 |
str(x) | 将对象 x 转换为字符串 |
repr(x) | 将对象 x 转换为表达式字符串 |
eval(str) | 用来计算在字符串中的有效Python表达式,并返回一个对象 |
tuple(s) | 将序列 s 转换为一个元组 |
list(s) | 将序列 s 转换为一个列表 |
chr(x) | 将一个整数转换为一个Unicode字符 |
ord(x) | 将一个字符转换为它的ASCII整数值 |
hex(x) | 将一个整数转换为一个十六进制字符串 |
oct(x) | 将一个整数转换为一个八进制字符串 |
bin(x) | 将一个整数转换为一个二进制字符串 |
运算符 | 描述 | 实例 |
---|---|---|
+ | 加 | 1 + 1 输出结果为 2 |
- | 减 | 1-1 输出结果为 0 |
* | 乘 | 2 * 2 输出结果为 4 |
/ | 除 | 10 / 2 输出结果为 5 |
// | 整除 | 9 // 4 输出结果为2 |
% | 取余 | 9 % 4 输出结果为 1 |
** | 指数 | 2 ** 4 输出结果为 16,即 2 * 2 * 2 * 2 |
() | 小括号 | 小括号用来提高运算优先级,即 (1 + 2) * 3 输出结果为 9 |
注意:混合运算优先级顺序:
()
高于**
高于*
/
//
%
高于+
-
运算符 | 描述 | 实例 |
---|---|---|
= | 赋值 | num1, float1, str1 = 10, 0.5, 'hello world' |
运算符 | 描述 | 实例 |
---|---|---|
+= | 加法赋值运算符 | c += a 等价于 c = c + a |
-= | 减法赋值运算符 | c -= a 等价于 c = c- a |
*= | 乘法赋值运算符 | c *= a 等价于 c = c * a |
/= | 除法赋值运算符 | c /= a 等价于 c = c / a |
//= | 整除赋值运算符 | c //= a 等价于 c = c // a |
%= | 取余赋值运算符 | c %= a 等价于 c = c % a |
**= | 幂赋值运算符 | c ** = a 等价于 c = c ** a |
比较运算符也叫关系运算符, 通常用来判断。
运算符 | 描述 | 实例 |
---|---|---|
== | 判断相等。如果两个操作数的结果相等,则条件结果为真(True),否则条件结果为假(False) | 如a=3,b=3,则(a == b) 为 True |
!= | 不等于 。如果两个操作数的结果不相等,则条件为真(True),否则条件结果为假(False) | 如a=3,b=3,则(a == b) 为 True如a=1,b=3,则(a != b) 为 True |
> | 运算符左侧操作数结果是否大于右侧操作数结果,如果大于,则条件为真,否则为假 | 如a=7,b=3,则(a > b) 为 True |
< | 运算符左侧操作数结果是否小于右侧操作数结果,如果小于,则条件为真,否则为假 | 如a=7,b=3,则(a < b) 为 False |
>= | 运算符左侧操作数结果是否大于等于右侧操作数结果,如果大于,则条件为真,否则为假 | 如a=7,b=3,则(a < b) 为 False如a=3,b=3,则(a >= b) 为 True |
<= | 运算符左侧操作数结果是否小于等于右侧操作数结果,如果小于,则条件为真,否则为假 | 如a=3,b=3,则(a <= b) 为 True |
运算符 | 逻辑表达式 | 描述 | 实例 |
---|---|---|---|
and | x and y | 布尔"与":如果 x 为 False,x and y 返回 False,否则它返回 y 的值。 | True and False, 返回 False。 |
or | x or y | 布尔"或":如果 x 是 True,它返回 True,否则它返回 y 的值。 | False or True, 返回 True。 |
not | not x | 布尔"非":如果 x 为 True,返回 False 。如果 x 为 False,它返回 True。 | not True 返回 False, not False 返回 True |
除却常用的整型、浮点型外还构建了一些常用的数据结构,分为可变类型与不可变类型(数据能够直接进行修改,如果能直接修改那么就是可变,否则是不可变):
id()
可以用来判断两个变量是否为同一个值的引用。
功能 | 语法 |
---|---|
判断数据是否存在 | 数据 in 变量 |
获取变量长度 | len(变量) |
获取数据所在下标 | 变量.index(数据, 开始位置下标, 结束位置下标) |
统计数据出现次数 | 变量.count(数据, 开始位置下标, 结束位置下标) |
字符串切片 | 序列[开始位置下标:结束位置下标:步长] |
替换特定字符串 | 字符串序列.replace(旧子串, 新子串, 替换次数) |
按特定字符分割字符串 | 字符串序列.split(分割字符, num) |
将多个字符串合并 | 字符或子串.join(多字符串组成的序列) 或 字符串 + 字符串 |
检测某个子串是否包含在这个字符串中 | 字符串序列.find(子串, 开始位置下标, 结束位置下标) |
返回某个子串在字符串中出现的次数 | 字符串序列.count(子串, 开始位置下标, 结束位置下标) |
检查字符串是否是以指定子串开头 | 字符串序列.startswith(子串, 开始位置下标, 结束位置下标) |
检查字符串是否是以指定子串结尾 | 字符串序列.endswith(子串, 开始位置下标, 结束位置下标) |
还有一些其他扩展实现以方便开发:
查找
rfind()
: 和find()功能相同,但查找方向为右侧开始。rindex()
:和index()功能相同,但查找方向为右侧开始。count()
:返回某个子串在字符串中出现的次数修改
capitalize()
:返回一个 将原字符串第一个字符转换成大写 的新字符串。title()
:返回一个 将原字符串每个单词首字母转换成大写 的新字符串。lower()
:返回一个 将原字符串中大写转小写 的新字符串。upper()
:返回一个 将原字符串中小写转大写 的新字符串。lstrip()
:返回一个 删除原字符串左侧空白字符 的新字符串。rstrip()
:返回一个 删除原字符串右侧空白字符 的新字符串。strip()
:返回一个 删除原字符串两侧空白字符 的新字符串。ljust()
:返回一个 原字符串左对齐,并使用指定字符(默认空格)填充至对应长度 的新字符串。rjust()
:返回一个 原字符串右对齐,并使用指定字符(默认空格)填充至对应长度 的新字符串,语法和ljust()相同。center()
:返回一个原字符串居中对齐,并使用指定字符(默认空格)填充至对应长度 的新字符串,语法和ljust()相同。注意:虽然Python实现了许多字符串修改操作函数,但是字符串为const变量不可在原基础上进行修改,即所有的增删操作都会生成新的字符串变量。
判断
isspace()
:如果字符串中只包含空白,则返回 True,否则返回 False。isdigit()
:如果字符串只包含数字则返回 True 否则返回 False。isalpha()
:如果字符串至少有一个字符并且所有字符都是字母则返回 True, 否则返回 False。isalnum()
:如果字符串至少有一个字符并且所有字符都是字母或数字则返 回 True,否则返回 False。功能 | 语法 |
---|---|
判断数据是否存在 | 数据 in 变量 |
获取变量长度 | len(变量) |
获取数据所在下标 | 变量.index(数据, 开始位置下标, 结束位置下标) |
统计数据出现次数 | 变量.count(数据, 开始位置下标, 结束位置下标) |
增加数据 | 列表序列.append(数据) |
追加数据中的每个元素至列表 | 列表序列.extend(数据) |
指定位置增加数据 | 列表序列.insert(位置下标, 数据) |
删除指定下标的数据 | 列表序列.pop(下标) |
删除指定下标的数据 | del 列表序列[下标] |
移除列表中数据的第一个匹配项 | 列表序列.remove(数据) |
排序 | 列表序列.sort( key=None, reverse=False) |
深拷贝 | 列表序列.copy() |
逆置 | 列表序列.reverse() |
清空 | 列表序列.clear() |
元组与列表类似,但是不支持增删改,只支持查询功能。
功能 | 语法 |
---|---|
判断数据是否存在 | 数据 in 变量 |
获取变量长度 | len(变量) |
获取数据所在下标 | 变量.index(数据, 开始位置下标, 结束位置下标) |
统计数据出现次数 | 变量.count(数据, 开始位置下标, 结束位置下标) |
特点:
- 集合可以去掉重复数据;
- 集合数据是无序的,故不支持下标
功能 | 语法 |
---|---|
判断数据是否存在 | 数据 in 变量 |
获取变量长度 | len(变量) |
追加数据 | 变量.add(数据) |
追加数据序列 | 变量.update(数据序列) |
删除集合中的指定数据 | 变量.discard(数据) |
随机删除集合中的某个数据 | 变量.pop(数据) |
功能 | 语法 |
---|---|
判断数据是否存在 | 数据 in 变量 |
获取变量长度 | len(变量) |
新增键值对或修改值 | 字典序列[key] = 值 |
删除指定下标的数据 | del 字典序列[key] |
清空 | 字典序列.clear() |
如果当前查找的key不存在则返回第二个参数 | 字典序列.get(key, 默认值) |
返回键值对的列表 | 字典序列.items() |
返回值的列表 | 字典序列.values() |
返回键的列表 | 字典序列.keys() |
函数定义方法
def 函数名(参数):
代码1
代码2
......
不定长参数也叫可变参数。用于不确定调用的时候会传递多少个参数(不传参也可以)的场景。此时,与C++不同Python选择将其位置或者关键字与参数打包,进行传递。
# 将传入的所有参数打包为元组传入
def user_info(*args):
print(args)
# ('TOM', 18)
user_info('TOM', 18)
# 将传入的所有参数和关键字打包为字典传入
def user_info(**kwargs):
print(kwargs)
# {'name': 'TOM', 'age': 18, 'id': 110}
user_info(name='TOM', age=18, id=110)
lambda表达式是一种特殊的函数,支持无参数,默认参数以及不定长参数:
lambda 参数: 表达式
在python,使用open函数,可以打开一个已经存在的文件,或者创建一个新文件,语法如下:
open(name, mode)
name:是要打开的目标文件名的字符串(可以包含文件所在的具体路径)。
mode:设置打开文件的模式(访问模式):只读、写入、追加等。
这里将常用的模式如下表:
模式 | 描述 |
---|---|
r | 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。 |
rb | 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。 |
r+ | 打开一个文件用于读写。文件指针将会放在文件的开头。 |
rb+ | 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。 |
w | 打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 |
wb | 以二进制格式打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 |
w+ | 打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 |
wb+ | 以二进制格式打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 |
a | 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
ab | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
a+ | 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。 |
ab+ | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。 |
常用函数表
功能 | 语法 |
---|---|
打开文件 | 文件对象 = open(目标文件, 访问模式) |
关闭文件 | 文件对象.close() |
写入文件 | 文件对象.write() |
从文件中读取num个字符 | 文件对象.read(num) |
将文件整体读取,返回以行为单位的列表 | 文件对象.readlines() |
读取一行数据 | 文件对象.readline() |
用来移动文件读取/写入位置 | 文件对象.seek(偏移量, 起始位置) |
注:seek函数的起始位置参数设置
- 0:文件开头
- 1:当前位置
- 2:文件结尾
功能 | 语法 |
---|---|
删除文件 | os.remove(目标文件名) |
创建文件夹 | os.mkdir(文件夹名字) |
删除文件夹 | os.rmdir(文件夹名字) |
获取当前路径 | os.getcwd() |
改变当前路径 | os.chdir(目录) |
获取文件列表 | os.listdir(目录) |
在实现类代码后可以通过继承重用已实现功能,并在此基础上实现更加个性化的功能,但是父类也可以通过声明为私有方法或变量来阻隔无必要的权限继承。
私有方法或变量实现方法如下:
class 类名():
# 私有属性
__属性名 = 值
# 私有方法
def __函数名(self):
代码
但是子类虽然继承了父类所允许的全部方法和变量,但是父类的初始化过程函数并不会在实例化时调用,所以需要自行调用__init__
函数进行参数初始化。对于不需要实例化和参数输入的函数,可以使用装饰器@staticmethod
来进行修饰,声明为静态实现,同时对于不需要实例化的函数可以使用装饰器@classmethod
进行修饰,但第一个参数需要是表示自身类的 cls 参数,可以来调用类的属性,类的方法,实例化对象等。
# 父类A
class A(object):
__name = "A"
def __init__(self):
self.__num = 1
@classmethod
def info_print(cls):
print(cls.__name)
@staticmethod
def info_print():
print('这是一个测试类....')
# 子类B
class B(A):
def __init__(self):
A.__init__(self) # super(B,self).__init__()
pass
捕捉处理异常的语法如下:
try:
可能发生异常的代码
except:
如果出现异常执行的代码
else:
没有异常执行的代码
finally:
无论是否异常都要执行的代码
自定义异常的实现示例如下:
# 自定义异常类,继承Exception
class ShortInputError(Exception):
def __init__(self, length, min_len):
self.length = length
self.min_len = min_len
# 设置抛出异常的描述信息
def __str__(self):
return f'你输入的长度是{
self.length}, 不能少于{
self.min_len}个字符'
def main():
try:
con = input('请输入密码:')
if len(con) < 3:
raise ShortInputError(len(con), 3)
except Exception as result:
print(result)
else:
print('密码已经输入完成')
main()
import 模块名
from 模块名 import 功能名
from 模块名 import *
import 模块名 as 别名
from 模块名 import 功能名 as 别名
Process进程类的参数说明
Process([group [, target [, name [, args [, kwargs]]]]])
Process创建的实例对象的常用属性
name:当前进程的别名,默认为Process-N,N为从1开始递增的整数
其他常用语句如下:
os.getpid()
获取当前进程编号os.getppid()
获取父进程编号子进程对象.daemon = True
守护主进程子进程对象.terminate()
销毁子进程import multiprocessing
导入进程包sub_process = multiprocessing.Process (target=任务名)
创建子进程并指定执行的任务sub_process.start()
启动进程执行任务sub_process.join()
:等待当前子进程执行结束sub_process.terminate()
:不管任务是否完成,立即终止当前子进程注意:为了保证子进程能够正常的运行,主进程会等所有的子进程执行完成以后再销毁,设置守护主进程的目的是主进程退出时子进程自动销毁,不让主进程再等待子进程去执行。当然也可以在主进程退出之前让手动调用子进程销毁。
线程类Thread参数说明
Thread([group [, target [, name [, args [, kwargs]]]]])
其他常用语句如下:
import threading
导入线程包sub_thread = threading.Thread(target=任务名)
创建子线程并指定执行的任务sub_thread.start()
启动线程执行任务sub_thread.join()
等待当前线程任务执行完毕,与sleep有类似效果threading.Thread(target=show_info, daemon=True)
守护主线程线程对象.setDaemon(True)
守护主线程mutex = threading.Lock()
创建互斥锁mutex.acquire()
上锁mutex.release()
释放锁因为多线程允许共享变量,但是多个线程访问共享数据会出现数据错误问题,而互斥锁能够妥当的解决该问题,但是需要注意死锁问题。
定义: 在函数嵌套的前提下,内部函数使用了外部函数的变量,并且外部函数返回了内部函数,使用外部函数变量的内部函数则被称为闭包
据此可知闭包的形成条件为:
可见其优点是可以暂存外部函数的一些状态,提高代码重用的效率,但是因此会增加内存的占用。当然如果闭包(内部函数)想要修改外部函数的某些变量,可以使用nonlocal
声明一下即可,闭包使用示例代码如下:
# 定义一个外部函数
def func_out(num1):
# 定义一个内部函数
def func_inner(num2):
# 这里本意想要修改外部num1的值,实际上是在内部函数定义了一个局部变量num1
nonlocal num1 # 告诉解释器,此处使用的是 外部变量a
# 修改外部变量num1
num1 = 10
# 内部函数使用了外部函数的变量(num1)
result = num1 + num2
print("结果是:", result)
print(num1)
func_inner(1)
print(num1)
# 外部函数返回了内部函数,这里返回的内部函数就是闭包
return func_inner
# 创建闭包实例
f = func_out(1)
# 执行闭包
f(2)
装饰器的功能特点:
装饰器的使用语法:
# 添加一个登录验证的功能
def check(fn):
def inner():
print("请先登录....")
fn()
return inner
def comment():
print("发表评论")
# 使用装饰器来装饰函数
comment_with_check = check(comment)
comment_with_check()
同时Python为固化已有功能在新函数上的场景提供了语法糖写法:
# 添加一个登录验证的功能
def check(fn):
print("装饰器函数执行了")
def inner():
print("请先登录....")
fn()
return inner
# 使用语法糖方式来装饰函数
@check
def comment():
print("发表评论")
comment()
copy.copy(变量)
函数是浅拷贝,只对可变类型的第一层对象进行拷贝,对拷贝的对象开辟新的内存空间进行存储,不会拷贝对象内部的子对象。copy.deepcopy(变量)
函数是深拷贝, 只要发现对象有可变类型就会对该对象到最后一个可变类型的每一层对象就行拷贝, 对每一层拷贝的对象都会开辟新的内存空间进行存储。在Python中需要通过正则表达式对字符串进行匹配的时候,可以使用 re
模块
# 导入re模块
import re
# 使用match方法进行匹配操作
result = re.match(正则表达式,要匹配的字符串)
# 如果上一步匹配到数据的话,可以使用group方法来提取数据
result.group()
另一种方式
# 导入re模块
import re
# 使用compile方法获取匹配器
reg = re.compile(正则表达式)
# 然后可以使用findall方法来获取字符串中所有匹配项
result = reg.findall(字符串)
注意 re.match() 根据正则表达式从头开始匹配字符串数据,而不是从任意位置开始。
单个字符匹配
多个字符匹配
匹配开头和结尾
匹配分组
上下文管理器是指在执行一段代码执行前,先执行一段代码用于一些预处理工作;执行这段代码之后再执行一段代码进行清理工作。构建上下文管理器生成类同时使用with
语句与之配合,便可实现。一个类只要实现了__enter__()
和__exit__()
这个两个上、下文方法,通过该类创建的对象我们就称之为上下文管理器。
class File(object):
# 初始化方法
def __init__(self, file_name, file_model):
# 定义变量保存文件名和打开模式
self.file_name = file_name
self.file_model = file_model
# 上文方法
def __enter__(self):
print("进入上文方法")
# 返回文件资源
self.file = open(self.file_name,self.file_model)
return self.file
# 下文方法
def __exit__(self, exc_type, exc_val, exc_tb):
print("进入下文方法")
self.file.close()
if __name__ == '__main__':
# 使用with管理文件
with File("1.txt", "r") as file:
file_data = file.read()
print(file_data)
另外一种实现方式是使用 @contextmanager
的装饰器,更进一步简化了上下文管理器的实现方式。通过 yield 将函数分割成上下文两个部分,将所跟的代码加载两者之间。
# 导入装饰器
from contextlib import contextmanager
# 装饰器装饰函数,让其称为一个上下文管理器对象
@contextmanager
def my_open(path, mode):
try:
# 打开文件
file = open(file_name, file_mode)
# yield之前的代码好比是上文方法
yield file
except Exception as e:
print(e)
finally:
print("over")
# yield下面的代码好比是下文方法
file.close()
# 使用with语句
with my_open('out.txt', 'w') as f:
f.write("hello , the simplest context manager")