pip
- pip list
- 查看已安装依赖
- pip -V
- 查看版本
- pip install 包名[==版本号]
- 安装依赖
- pip uninstall 包名
- 卸载
- pip freeze > requirements.txt
- 将项目依赖的包的名称和版本导入到指定文本中
- pip install -r requirements.txt
- 使用pip安装文件中所标的所有依赖
算数运算符
除了加减乘除外,还有
- 取整除
//
- 取余数
%
- 幂
**
逻辑运算符
- and
- or
- not
变量
Python是弱类型语言,定义变量不需要指定类型
变量类型
- 数字型
- int
- float
- bool
- True 非0即真
- False 0
- complex
- 非数字型
- 字符串
- 列表
- 元组
- 字典
变量的格式化输出
格式化字符串 | 含义 |
---|---|
%s | 字符串 |
%d | 有符号十进制数,%06d表示输出的整数显示位数,不足的地方使用0补全 |
%f | 浮点数,%.02f表示小数点后只显示两位 |
%% | 输出% |
变量的命名规则
- Python中标识符是区分大小写的
变量进阶
变量的引用
Python中函数的参数传递以及返回值都是靠引用传递的
引用的概念
在python
中
- 变量和数据分开存储
- 变量中保存着数据在内存中的地址
- 变量中记录数据的地址,就叫做引用
- 使用
id()
函数可以查看变量总保存数据所在的内存地址
如果变量已经被定义,当给一个变量赋值时,变量改为对新赋值的数据引用
可变和不可变类型
- 不可变类型,内存中的数据不允许被修改
- 数据类型:
int
,bool
,float
,complex
,long(2.x)
- 字符串
str
- 元组
tuple
- 数据类型:
- 可变类型,内存中的数据可以被修改
- 列表
list
- 字典
dict
- 注意:字典的
key
只能使用不可变类型的数据
- 注意:字典的
- 列表
注意
- 可变类型的数据变化,是通过方法来实现的
- 如果给一个可变类型的变量,赋值了一个新的数据,引用会修改
- 变量不再对之前的数据引用
- 变量改为对新赋值的数据引用
哈希hash
Python
中内置有一个函数叫hash(o)
- 接收一个不可变类型的数据作为参数
- 返回结果是一个整数
哈希
是一种算法,其作用就是提取数据的特征码(指纹)- 相同的内容得到相同的结果
- 不同的内容得到不同的结果
- 在
Python
中,设置字典的键值对时,会首先对key
进行hash
已决定好在内存中如何保存数据,以方便后续对字典的操作:增删改查- 键值对的
key
必须是不可改变类型数据 - 键值对的
value
可以是任意类型的数据
- 键值对的
局部变量和全局变量
-
函数不能直接需修改全局变量的引用——使用赋值语句修改全局变量的值
-
如何在函数内部修改全局变量的值
- 使用
global
进行声明
- 使用
-
全局变量定义的位置
- 应该将全局变量定义在其他函数的上方
-
全局变量命名的建议
- 在定义全局变量时,有些公司会有一些开发要求
- 例如,增加
g_
或者gl_
前缀
函数
函数的文档注释
-
在开发中,如果希望给函数添加注释,应该在定义函数的下方,使用连续的三对引号
-
在连续的三对引号之间编号对函数的说明文字
def multiple_table(): """九乘九,乘法表"""
-
在函数调用位置,使用快捷键
ctrl+Q
可以查看函数的说明信息
因为函数体相对比较独立,函数定义的上放,应该和其他代码(包括注释)保留两个空行
- 给函数增加注释,包括对参数的说明
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Bdn4eNqC-1615807570855)(/images/python_1.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uV7AYnvD-1615807570856)(/images/python_2.png)]
缺省参数
如对列表的排序
list_1.sort()
list_2.sort(reverse=True)
指定函数的缺省函数
定义函数时,在参数列表中直接指定即可
如:print_info(name,gender=True):
缺省参数的注意事项
- 缺省参数的定义位置
- 必须保证带有默认值的缺省参数在参数列表末尾
- 调用带多个缺省参数的函数
- 在调用函数时,如果有多个缺省参数,需要指定参数名,这样解释器才能知道参数的对应关系
多值参数
定义支持多值参数的函数
-
有时可能需要一个函数能够处理的参数个数是不确定的,这时候就可以使用多值参数
-
python
中有两种多值参数- 参数名前增加一个
*
可以接收元组 - 参数名前增加两个
*
可以接收字典
- 参数名前增加一个
-
一般在给多值参数命名时,习惯使用以下两个名字
*args
——存放元组参数arguments
缩写
**kwargs
——存放字典参数keyword
缩写
-
示例
def func(*args,**kwargs): print(args) print(kwargs) func(1,2,3,name='yfx',age=22)
元组和字典的拆包
def func(*args,**kwargs):
print(args)
print(kwargs)
gl_nums=(1,2,3)
gl_dict={'name':'yfx','age':23}
func(*gl_nums,**gl_dict)
模块
模块是Python程序架构的 一个核心概念
- 模块就好比是工具包,要想使用这个工具包中的工具,就需要导入import这个模块
- 每一个以py结尾的python源代码文件都是一个模块
- 在模块中定义的全局变量、函数都是模块能够提供给外界直接使用的工具
模块名也是一个标识符
- 由字母、下划线和数字组成
- 不能数字开头
- 不能与关键字重名
模块的两种导入方式
第一种:import导入
import 模块名1,模块名2
提示:在导入模块时,每个导入应该独占一行
import 模块名1
import 模块名2
如果模块名过长,可以使用
as
指定模块的别名
注意,模块别名应该使用大驼峰命名法
第二种:from…import导入
- 如果希望从某个模块中,导入部分工具,可以使用
from..import
- 导入之后
- 不需要通过
模块名.
- 可以直接使用模块提供的工具——全局变量、函数、类
- 不需要通过
注意,如果两个模块存在同名函数,那么后导入模块的函数,会覆盖掉先导入的函数
- 一旦发生冲突,可以使用
as
关键词,给其中一个工具起一个别名
第三种:from…import* (了解)
不需要使用模块名.
,但是易发生重名冲突
这种方式不推荐,因为函数重名并没有任何的提示,出现问题不好排查
模块的搜索顺序(了解)
python的解释器在导入模块时,会:
- 搜索当前目录指定模块名的文件,如果有就直接导入
- 如果没有,再搜索系统目录
在开发时,给文件起名,不要和系统的模块文件重名!
python中的每一个模块都有一个内置属性_file_
可以查看模块的完整路径
导入文件的细节
- 一个独立的python文件就是一个模块
- 在导入文件时,所有没有任何缩进的代码都会被执行一遍
实际开发场景中
- 在实际开发中,每一个模块都是独立开发的,大多有专人负责
- 开发人员通常会在模块下方,增加一些测试的代码
- 仅在模块内使用,而被导入到其他文件中不需要执行
__name___属性
__name__
属性可以做到,测试模块的代码,只在测试情况下被运行,而在被导入时,不会执行!__name__
是python的一个内置属性,记录着一个字符串- 如果是被其他文件 导入的,
__name__
就是模块名 - 如果是当前执行的程序,
__name__
就是__main__
在很多python
文件中都会看到以下格式的代码
# 导入模块
# 定义全局变量
# 定义类
# 定义函数
# 在代码下方
def main():
#...
pass
# 根据__name__判断是否执行以下代码
if __name__ == "__main__":
# 测试代码
此时测试代码,在本模块被import后不会执行
包
概念
- 包是一个包含多个模块的特殊目录
- 目录下有一个特殊文件__init__.py
- 包名的命名方式和变量名一致
好处
- 使用
import 包名
可以一次性导入包中所有的模块
__init__.py
- 要在外界使用包中的模块,需要在
__init_——。py
中指定对外界提供的模块列表
# 从当前目录 导入 模块列表
from . import send_message
from . import receive_message
发布模块和安装模块
建议百度,不同平台不一样
高级变量类型
列表
-
尽管python的列表可以存储不同类型的数据,但是在开发中,更多的应用场景是列表存储相同类型的数据
-
定义一个列表:
list01=[]
-
输入
list.
按下TAB
键,ipython会提示列表能够使用的方法
分类 | 关键字/函数/方法 | 说明 |
---|---|---|
增加 | insert(索引,数据) | 指定位置插入数据 |
append(数据) | 末尾追加数据 | |
extend(列表2) | 将列表2的数据追加到列表 | |
修改 | 列表[索引]=数据 | |
删除 | del 列表[索引] | 删除指定索引的数据 |
remove[数据] | 删除第一个出现的指定数据 | |
pop | 删除末尾数据 | |
clear | 清空列表 | |
统计 | len(列表) | 列表长度 |
列表.count(数据) | 数据在列表中出现的次数 | |
排序 | sort() | 升序排序 |
sort(reverse=True) | 降序排序 | |
reverse() | 逆序,反序 | |
索引 | .index(数据) | 查找数据所在的索引 |
列表的循环遍历
for name in list_:
print(name)
元组
Tuple
元组与列表类似,不同之处在于元组不能修改- 元组表示多个元素组成的序列
- 元组在python开发中,有特定的应用场景
- tuple_1=(“zhangsan”, 18, 1.75)
- 只有一个元素的元组需要加逗号
tuple01=(5,)
元组的常用操作
- count
- index
元组的应用场景
- 函数的参数和返回值,使一个函数可以接收任意多个参数,或者一次返回多个数据
- 格式字符串,格式化字符串后面的
()
本质上就是一个元组 - 让列表不可以被修改,以保护字符串
元组和列表之间的转换
list
函数可以把元组转换为列表tuple
函数可以把列表转换为元组
元组作为返回值
-
可以省略括号
-
接收时可以写成
def func(): return 1,2 a,b=func()
字典
字典的定义
dictionary
(字典)是除列表以外python
之中最灵活的数据类型- 字典同样可以用来存储多个数据
- 通常用于存储描述一个
物体
的相关信息
- 通常用于存储描述一个
- 和列表的区别
- 列表是有序的对象集合
- 字典是无序的对象集合
- 字典用
{}
来定义 - 字典使用键值对存储数据,键值对之间用
,
分隔- 键
key
是索引 - 值
value
是数据 - 键和值之间使用
:
分隔 - 键必须是唯一的
- 值可以取任何数据类型,但
键
只能使用字符串、数字或元组
- 键
- 字典的取值
dict[键]
- 字典的增加/修改 dict[键]=值
- 字典的删除dict.pop(键)
- 统计键值对数量
len
- 合并字典
dict.update(新的字典)
- 清空字典
dict.clear()
字典的循环遍历
在实际开发中,由于字典中每一个键值对保存数据的类型是不同的,所以针对字典的循环遍历需求并不是很多
方法:for循环遍历键,通过键找到值
字符串
字符串常用操作
len
count(字符串)
统计小字符串在大字符串中出现的次数index(字符串)
某一个子字符串出现的位置
- 判断类型
方法 | 说明 |
---|---|
string.isspace() | 如果string中只包含空格(包括\n\t\r),则返回True |
string.isalnum() | 如果string至少有一个字符并且所有字符都是字母或数字,返回True |
string.isalpha() | 判断是否全是字母 |
isdecimal() | 判断是否只包含数字,全角数字 |
isdigit() | 判断是否只包含数字,全角数字,(1),\u00b2 |
isnumeric() | 判断是否只包含数字,全角数字,汉字数字 |
istitle() | 判断是否是标题化字符串(每个单词首字母大写) |
islower() | 至少包含一个区分大小写的字符,并且都是小写 |
isupper() | 至少包含一个区分大小写的字符,并且都是大写 |
- 查找和替换
方法 | 说明 |
---|---|
startswith(str) | 是否以str开头 |
endswith(str) | 是否以str结尾 |
find(str,start=0,end=len(string)) | 检测str是否包含在string中,如果start和end指定范围,则检查是否包含在指定范围内,如果是返回开始的索引值,否则返回-1 |
rfind() | 从右边开始查找 |
index() | 与find类似,不过str不在string中会报错 |
rindex() | 从右边开始查找 |
replace(old_str,new_str,num=string.count(old)) | 把string中的old_str替换成new_str,如果num指定,则替换不超过num次 |
- 文本对齐
方法 | 说明 |
---|---|
ljust(width) | 左对齐,ctrl+Q 查看具体用法 |
rjust(width) | 右对齐 |
center(width) | 居中 |
- 大小写转换
方法 | 说明 |
---|---|
capitalize() | 第一个字符大写 |
title() | 每个单词首字母大写 |
lower() | |
upper() | |
swapcase() | 大小写翻转 |
- 去除空白字符
方法 | 说明 |
---|---|
lstrip() | 裁掉左边开始的空白字符 |
rstrip() | 裁掉右边开始的空白字符 |
strip() | 裁掉两边的空白字符 |
- 拆分和连接
方法 | 说明 |
---|---|
partition(str) | 将string分成str前面,str,str后面三部分 |
rpartition(str) | 同上,不过从右边开始查找 |
split() | |
splitlines() | 按照\r \n \r\n分隔 |
string.join(seq) | 以string作为分隔符,将seq中所有的元素(的字符串表示)合并为一个新的字符串 |
字符串的切片
- 切片方法适用于:字符串、列表、元组
- 字符串逆序
str[-1::-1]
或者str[::-1]
公共方法
Python内置函数
内置函数:无需import可以直接使用的函数
函数 | 描述 | 备注 |
---|---|---|
len(item) | 计算容器中元素个数 | |
del(item) | 删除扮靓 | del有两种方式 |
max(item) | 返回容器中元素最大值 | 如果是字典,只针对key比较 |
min(item) | 返回容器中元素最小值 | 如果是字典,只针对key比较 |
cmo(item1,item2) | 比较两个值,-1小于/0等于/1大于 | python3取消了cmp函数 |
注意
- 字符串比较符合以下规则:‘0’<‘A’<‘a’
切片
切片是左闭右开的
字典是无序的,不能进行切片
对比列表追加方法
list1=[1,2,3]
list1+[4,5]和list1.extend([4,5])的区别是
extend改变了list1,而`+`返回新的list
list1.append(6)
list1.append([7,8])
list1=[1,2,3,4,5,6,[7,8]]
成员运算符
in
和not in
对字典使用时,针对的是键
完整的for循环语法
for 变量 in 集合:
循环体代码
else:
for循环完整地执行完成后(没有中途break),执行else语句代码
类和对象
类的设计
- 类名使用大驼峰命名法:
GoodPerson
- 内置函数
dir
- 使用
dir
传入标识符/数据,可以查看对象内的所有属性和方法 - 变量,数据,函数都是对象
- 使用
self参数
由哪一个对象调用的方法,方法内部的self就是哪个对象的引用(类似C++/Java的this)
- 在类封装的方法内部,
self
就表示当前调用方法的对象自己 - 调用方法时,程序员不需要传递
self
参数 - 在方法内部
- 可以通过
self
访问对象属性 - 也可以通过
self
,调用其他对象的方法
- 可以通过
给对象增加属性
- 在类外,对对象直接添加,不推荐
tom.name='TOM'
初始化方法
- 当使用类名()创建对象时,会自动执行以下操作
- 为对象在内存中分配空间——创建对象
- 为对象的属性设置初始值——初始化方法
init
- 这个初始化方法就是
_init_
方法,该方法是对象的内置方法
_init_
方法是专门用来定义一个类具有哪些属性的方法!
def __init__(self,name,age):
self.name=name
self.age=age
def show(self):
print('My name is %s'%self.name)
print('My age is %s'%self.age)
内置方法和属性
_del_
方法- 对象被从内存中销毁前,会被自动调用
- 如果希望在对象被销毁前,再做一些事情,可以考虑
_del_
方法
_str_
方法- 返回对象的描述信息,print函数输出使用
- 必须返回一个字符串
身份运算符
身份运算符用于比较两个对象的内存地址是否一直(即是否是同一个对象的引用)
- 在
Python
中针对None
比较时,建议使用is
判断is
is not
is
和==
的区别is
用于判断两个变量引用对象是否是同一个==
用于判断引用变量的值是否相等
私有属性和私有方法
- 定义方式
- 定义属性或者方法时,在属性名或方法名前增加两个下划线,定义的就是私有属性和私有方法
- 子类对象不能直接访问父类的私有属性或私有方法,可通过父类的公有方法间接访问
伪私有属性和私有方法(了解)
在日常开发中,不要使用这种方式,访问对象的私有属性或私有方法
在Python中,没有真正意义的私有
- 在给属性、方法命名时,实际上是对名称做了一些特殊处理,使得外界无法访问
- 处理方式:在名称前加上
_类名
=>_类名__名称
(前面一个杠,后边两个杠)
继承
单继承
写法:class Dog(Animal):
方法的重写
重写父类方法有两种情况
-
覆盖父类的方法
-
对父类方法进行扩展
-
在需要的位置使用
super().父类方法
来调用父类方法的执行class Cat(Animal): def eat(self): super().eat() print("Cat is eating !")
-
super()
就是使用父类创建出来的对象
-
多继承
- 写法:
class 子类名(父1,父2...)
- 应避免父类之间存在同名属性或方法的情形,此情形下应尽量避免使用多继承
MRO——方法搜索顺序(了解)
-
Python中针对类提供了一个内置属性
__mro__
,可以查看方法搜索顺序 -
MRO是
method resolution order
,主要用于在多继承时判断方法,属性的调用路径class A: pass class B: pass class C(A,B): pass print(C.__mro__)
结果: (<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
新式类与旧式类
object
是python中为所有对象提供的基类,提供有一些内置的属性和方法,可以使用dir
函数查看
新式类
:以object
类为基类的类,推荐使用经典类
:不以object
类为基类的类,不推荐使用- python3中定义的类,如果没有指定父类,默认是新式类
- 为了保证编写的代码能够在python2和python3的解释器下运行,如果没有父类,建议统一继承
object
class A(object):
多态
多态不同的子类对象调用相同的父类方法,产生不同的执行结果
类是一个特殊的对象
Python中一切皆对象
- 在程序运行时,类同样会被加载到内存
- 在
Python
中,类是一个特殊的对象——类对象 - 在程序运行时,类对象在内存中只有一份,使用一个类可以创建出很多个对象实例
- 除了封装实例的属性和方法外,类对象还可以拥有自己的属性和方法
- 通过类名.的方式,可以访问类的属性或调用类的方法
类属性和实例属性
例如:
class Group:
count = 0
def __init__(self):
Group.count += 1
- 此时,每创建一个对象,Group类的count就会+1
属性的获取机制(了解)
访问类属性有两种方式
- 类名.类属性
- 对象名.类属性(不推荐)
- 会导致歧义,如果写出
对象.类属性=值
,只会给对象添加一个属性,而不会影响类属性的值
- 会导致歧义,如果写出
类方法
类方法语法如下
class Person:
@classmethod
def work(cls):
print("Working now")
静态方法
- 如果一个方法,不需要访问实例属性,也不需要访问类属性,则可以将其封装成一个静态方法
class Cat:
@staticmethod
def run():
print("running now!")
Cat.run()
单例设计模式
- 设计模式:
- 设计模式是前人工作的总结和提炼,通常,被人们广泛流传的设计模式都是针对某一特定问题的成熟的解决方案。
- 使用设计模式是为了可重用代码、让代码更容易被他人理解,保证代码的可靠性
- 单例设计模式
- 目的:让类创建的对象,在系统中只有唯一一个实例
- 每次执行类名()返回的对象,内存地址都是相同的
- 单例设计模式的应用场景
- 打印机对象
- 音乐播放器对象
__new__方法
-
使用
类名()
创建对象时,python解释器会先调用__new__
方法为对象分配空间 -
__new__
是一个由object
基类提供的内置静态方法,主要作用由两个:- 在内存中为对象分配内存空间
- 返回对象的引用
-
python解释器获得对象的引用后,将引用作为第一个参数,传递给
__init__
方法重写__new__方法的代码非常固定
-
重写
__new__
方法一定要return super().__new__(cls)
-
否则python的解释器得不到分配了空间的对象引用,就不会调用对象的初始化方法
-
注意:
__new__
是一个静态方法,在调用时需要主动传递cls
参数
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-POpScgrh-1615807570858)(/images/python_3.png)]
单例设计模式案例
class MusicPlayer(object):
instance=None
# 初始化动作记录
init_flag=False
def __new__(cls, *args, **kwargs):
if MusicPlayer.instance is None:
cls.instance=super().__new__(cls)
return cls.instance
def __init__(self):
if MusicPlayer.init_flag:
return
MusicPlayer.init_flag=True
print("初始化播放器")
异常
异常的概念
- 程序在运行时,如果python解释器遇到一个错误,会停止程序的执行,并且提示一些错误信息,这就是异常
- 程序停止执行并且提示错误信息这个动作,我们称之为:抛出(ralse)异常
- 程序开发时,很难将所有的特殊情况都处理的面面俱到,通过异常捕获可以针对突发事件做集中的处理,从而保证程序的稳定性和健壮性
捕获异常
简单的捕获异常语法
try:
尝试执行的代码
except:
出现错误的处理
错误类型捕获
- 在程序执行中,可能会遇到不同类型的异常,并且需要针对不同类型的异常,做出不同的响应,这个时候,就需要捕获错误类型了
try:
num=int(input("Enter a num:"))
result=8/num
print("result is %.1f"%result)
except ZeroDivisionError:
print("除0错误!")
except ValueError:
print("输入数字有误!")
未知异常捕获
try:
num=int(input("Enter a num:"))
n=8/num
print("result is %.1f"%n)
except ValueError:
print("输入数字有误!")
except Exception as result:
print("未知错误%s"%result)
异常捕获完整语法
try:
pass
except 错误类型1:
pass
except (错误类型2,错误类型3):
pass
except Exception as result:
print(result)
else:
没有异常时,执行的代码
finally:
无论是否出现异常,都会执行的代码
异常的传递
- 异常的传递——当函数/方法执行出现异常时,会将异常传递给方法/函数的调用一方
- 如果传递到主程序,仍然没有异常处理,程序才会被终止
提示
- 在开发中,可以在主函数中增加异常捕获
- 而在主函数中调用的其他函数,只要出现异常,都会传递到主函数的异常捕获中
- 这样就不需要再代码中,增加大量的异常捕获,能够保证代码的整洁
def func1():
return 8/int(input("ENter a num:"))
def func2():
print(func1())
try:
func2()
except Exception as abc:
print("错误类型:%s"%abc)
raise异常
应用场景
-
在开发中,除了代码执行出错,python解释器会抛出异常之外
-
还可以根据应用程序特有的业务需求主动抛出异常
-
案例:
def input_password(): pwd = input("输入密码") pwd_len = len(pwd) if pwd_len < 8: ex=Exception("密码少于8位") raise ex return pwd try: print(input_password()) except Exception as result: print("发生错误!错误类型:%s" % result)
文件
文件的基本操作
1.操作文件的套路
在计算机中要操作文件的套路非常固定,一共三个步骤
- 打开文件
- 读写文件
- 读:将文件内容读入内存
- 写:将内存内容写入文件
- 关闭文件
2.操作文件的函数/方法
-
在python中要操作文件需要记住1个函数和3个方法
序号 方法 说明 1 open 打开文件,并且返回文件操作对象 2 read 将文件内容读取到内存 3 write 将指定内容写入文件 4 close 关闭文件 -
open
函数负责打开文件、并且返回文件独享 -
read/write/close
三个方法都需要通过文件对象来调用
3.read方法
- open函数的第一个参数是要打开的文件名(区分大小写)
- 文件存在,返回文件操作对象
- 不存在,则会抛出异常
- read方法可以一次性读入并返回文件的所有内容
- close方法负责关闭文件
- 如果忘记关闭文件,会造成系统资源消耗,而且会影响到后续对文件的访问
- 注意:方法执行后,会把文件指针移动到文件的末尾
提示
- 在开发中,通常会先编写打开和关闭的代码,再编写中间针对文件的读写操作
文件指针
- 文件指针标记从哪个位置开始读取数据
- 第一次打开文件时,通常文件指针会指向文件的开始位置
- 当执行了
read
方法后,文件指针会移动到读取内容的末尾- 默认情况下会移动到文件末尾
思考
- 如果执行了一次
read
方法,读取了所有内容,那么再次调用read
方法,还能得到内容吗?- 答案:不能!因为文件指针已经在文末。
4.打开文件的方式
- open函数默认以只读方式打开文件,并且返回文件对象
语法如下:
f=open("文件名",“访问方式”)
访问方式 | 说明 |
---|---|
f | 以只读方式打开文件。默认方式 |
w | 以只写方式打开文件。如果文件存在会被覆盖。文件不存在,则创建新文件 |
a | 以追加方式打开文件。文件不存在,则创建新文件 |
r+ | 以读写方式打开文件。文件不存在,则抛出异常 |
w+ | 以读写方式打开文件。文件存在,则被覆盖。文件不存在,则创建新文件 |
a+ | 以读写方式打开文件。文件存在,则指针放结尾。不存在,则创建新文件。 |
提示:
- 频繁地移动文件指针,会影响文件地读写效率,开发中更多地时候,会以只读,只写的方式来操作文件
5.按行读取文件内容
- read方法默认会把文件的所有内容一次性读取到内存
- 如果文件太大,对内存的占用会很严重
readline方法
readline
方法可以一次读取一行内容- 方法执行后,会把文件指针移动到下一行,准备再次读取
读取大文件的正确姿势
# 打开文件
file = open("D:\\new.txt")
while True:
# 读取一行内容
text = file.readline()
# 判断是否读取到内容
if not text:
break
# 每读取一行的末尾已经有了一个'\n'
print(text, end="")
# 关闭文件
file.close()
复制文件案例
file1=open("file1.txt")
file2=open("file2.txt","w")
while True:
text=file1.readline()
if not text:
break
file2.write(text)
file2.close()
file1.close()
6.文件/目录的常用管理操作
- 在终端/文件浏览器,中可以执行常规的文件/目录管理操作,例如:
- 创建、重命名、删除、改变路径、查看目录内容…
- 在
python
中,如果希望实现上述功能,需要导入os
模块
文件操作
序号 | 方法名 | 说明 | 示例 |
---|---|---|---|
1 | rename | 重命名文件 | os.rename(源文件名,目标文件名) |
2 | remove | 删除文件 | os.remove(文件名) |
目录操作
序号 | 方法名 | 说明 | 示例 |
---|---|---|---|
1 | listdir | 目录列表 | os.listdir(目录名) |
2 | mkdir | 创建目录 | os.mkdir(目录名) |
3 | rmdir | 删除目录 | os.rmdir(目录名) |
4 | getcwd | 获取当前目录 | os.getcwd() |
5 | chdir | 修改工作目录 | os.chdir(目标目录) |
6 | path.isdir | 判断是否是文件 | os.path.isdir(文件路径) |
提示:文件或者目录操作都支持相对路径和绝对路径
7.文本文件的编码格式
- 文本文件存储的内容是基于字符编码的文件
- python2默认使用ASCII编码
- python2中不能直接使用中文,要使用则需在文件第一行
# *-* codeing:utf-8 *-*
- 或者
# coding=utf-8
- 在python2中遍历含中文字符串会乱码,需要在字符串前加u
- u"hello世界"
- 告诉解释器这是一个utf-8格式的字符串
- python3默认使用UTF-8编码
ASCII编码和UNICODE编码
- 计算机中只有256个ASCII字符
- 一个ASCII在内存中占用1个字节,2的8次方为256
UTF-8编码格式
- 计算机中使用1~6个字节来表示一个
utf-8
字符,涵盖了地球上几乎所有地区的文字 - 大多数汉字会使用3个字节表示
utf-8
是UNICODE
编码的一种编码格式
eval函数
evaluate:评估的缩写
eval()
函数十分强大——将字符串当成有效的表达式来求值,并返回计算结果
# 基本的数学计算
result=eval("2*3+1")
print(result)
# 字符串重复
str="'#'*10"
print(eval(str))
# 将字符串转换成列表
str="[1,2,3,4,5]"
print(type(eval(str)))
# 将字符串转换成字典
str="{'name':'xiaoming','age':18}"
print(type(eval(str)))
不要滥用eval
在开发时千万不要使用
eval
直接转换input
的结果
用户可以通过输入__import__('os').system('ls')
等,对系统发出命令!
等价于
import os
os.system("终端命令")
补充知识点
-
id()
可以查看内存地址 -
可以将
None
赋值为任何一个变量 -
随机数
- import random
- random.randint(a,b) 返回[a,b]之间的整数,包含a和b
-
函数调用不能放在函数定义之前,因为python是解释型语言,一行一行执行的
-
Pycharm中
F8 Step Over
可以单步执行,会把函数调用看作一行代码直接执行F7 Step into
可以单步执行代码,如果是函数会进入函数内部
-
pyc
文件:- c是
compiled
编译过的意思 - python解释器为了提高程序执行速度,将模块的源码转换为**字节码
- c是
-
# todo注释
提示自己有什么活还没干 -
返回值是元组时,省略小括号
-
列表变量调用
+=
本质上是在执行列表变量的extend
方法,不会修改变量的引用p- 所以在函数中,普通变量
+=
不会影响外界数据,但是列表的+=
会影响x5
- 所以在函数中,普通变量
-
python能够自动将一对括号内部大的代码连接在一起,可以放心换行
-
python占位符pass,无意义,用来暂时保证程序不报错
-
object是所有类的基类
-
join(列表、字典、元组)
将序列中的元素以指定的字符连接生成一个新的字符串-
要求列表…中是字符串
-
list1=["1","2","3","4"] str1=",".join(list1) print(str1) list2=[1,2,3,4] str2=",".join(str(n) for n in list2) print(str2)
-