#文件操作open、close
打开一个文件供读写
file = open(file, mode=xx)
用完之后一定要记得关闭
file.close()
#文件的方法:
file.readline():通常只对文本文件进行读取,读到文件为返回空字符串,会返回回车符等转义字符
file.readlines(lines):读取 lines 行的数据,返回每一行数据字符串组成的列表
file.read(size):读取指定字节数的数据,返回每个字节字符组成的列表
file.read():读取文件中所有剩余的字节数,返回一个大的字符串
file.writelines([a,b,c]):将字符串列表写入文件,不自动加回车
file.flush():将缓冲区的文件缓冲写入磁盘
#文件的打开方式
't':文本文件方式打开
'r':只读,默认值
'w':只写,删除源文件内容;若不存在则创建
'x':创建一个新文件,并以写模式打开这个文件
'a':以只写模式打开一个文件,在原文件后面追加
#二进制文件
文件中以字节为存储的单位,不以字符为单位进行存储的文件
以bytes进行存储
#二进制文件操作方法
打开时用模式'b'打开
file.read(size=-1):读取二进制文件size字节,而不是size个字符
#字节串,也叫字节序列bytes
作用:存储以字节为单位的数据
字节串是不可变的字节序列
字节串中每个元素是0-255之间的整数
#字节串操作
创建新的字节串:b''
创建非空字节串:b'ABCD' b"ABCD" b"""ABCD""" b'''ABCD''' b'\x41\x11'
#字节串的生成函数
bytes():生成一个空字节串等同于b''
bytes(整型list):用可迭代对象初始化一个字符串
bytes(整数n):生成值为0,长为n的字节串
bytes(str,encoding='utf-8')
#字节串的运算
+ += * *= 和字符串完全相同
< <= > >= == !=
in / not in
索引/切片
#bytes与str的区别
bytes存储字节(0-255)
str存储Unicode字符(0-65536)
可以相互转换
b = s.encode(encoding='utf-8')
s = b.decode(encoding='utf-8')
#字节数组bytearray
可变的字节序列
#bytearray创建函数
bytearray():创建空的字节数组
bytearray(整数n):创建长度为n的、值为0的字节数组
bytearray(整数可迭代对象)
bytearrar(字符串,encoding="utf-8)
#bytearray操作方式与list完全相同
+ += * *=
< <= > >= == !=
in / not in
索引/切片
#文件读写其他方法
file.tell():返回当前文件流的绝对位置
file.seek(offset, whence = 0):
改变文件指针的位置,相对于whence位置改变offset
whence:0:文件头 1:当前文件指针位置 2:文件末尾
#sys.stdin stdout stderr
这三个文件一开始就已经加入缓冲区
sys.stdout是一个对象,绑定了一个文件流对象,可以用文件流文件的所有方法
print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)
向file的文件流对象中写入数据,flush代表立即写入文件还是写入缓冲区
sys.stderr是一个对象,绑定了一个错误流文件,向该文件写错误信息,包括raise触发的错误
#重定向
python test.py 2> a.txt
文件 文件描述符
输入文件 0
输出文件 1
错误输出文件 2
#练习:实现文件拷贝
def file_copy(src, dst, new_name):
src_file = open(src, 'rb')
if not dst.endswith('/'):
dst += '/'+ new_name
else:
dst += new_name
dst_file = open(dst,'wb')
while True:
read_data = src_file.read(1000)
if read_data == b'':
break
print("write %d bytes", dst_file.write(read_data))
src_file.close()
dst_file.close()
import os,sys
if len(sys.argv) != 4:
raise ValueError("This function need 3 param, %d is given" % (len(sys.argv)-1))
file_copy(sys.argv[1], sys.argv[2], sys.argv[3])
#调用方式:python test.py ./file.txt ./copy_test/ new_copy_file.txt
#注释:python test.py 源文件目录+文件名 目标文件路径 目标文件文件名
#类class
类是同来描述对象属性和行为的工具,用类可以创建对象
#类的创建
class class_name(继承列表):
"""文档字符串
"""
实例方法
类变量
类方法@aclassmethod
静态方法@staticmethod
说明:
类名必须是标识符
类名实质上就是变量,它绑定了一个类
(潜规则)类的定义后要加两个空行,告诉解释器类定义完成;否则在极少数情况下无法解析
实例对象创建:类名(传参列表)
实例有自己的名字空间,可以为一个实例添加变量(实例变量/方法)
#添加实例对象(直接添加即可)
class Cat():
pass
cat1 = Cat()
cat1.kinds = "erha"
#首次赋值创建实例变量,再次赋值改变引用关系
#删除实例变量
del 实例.变量
#删除实例
del 实例
#del作用总结
1、删除变量
2、删除列表中元素
3、删除字典中键值对
4、删除实例属性
#实例方法
class class_name(继承列表):
def 实例方法名(self, argv1, argv2, ...):
"""文档字符串
"""
语句块
说明:
实例方法第一个参数代表自己,一般用self命名
#调用实例方法
实例.方法(参数列表)
或
类名.方法(实例,参数列表)
#初始化方法
作用:创建对象时进行初始化
语法:
class class_name(继承列表):
def __init__(self[,参数列表]):
语句块
说明:
1、初始化方法名必须为__init__
2、一个类中只能有一个__init__方法
3、在实例创建后自动调用
4、如果需要return,必须return None
#阶段示例:
class Animal():
def __init__(self, str_name):
self.name = str_name
def eat(self, food_name):
print("%s is eating %s" % (self.name, food_name))
def drink(self, drink_name):
print("%s is drinking %s" % (self.name, drink_name))
cat = Animal("cat")
dog = Animal("dog")
cat.eat("cookie")
dog.drink("orange")
#类变量
在class中创建的变量,属于这个类,不属于此类的实例
类变量可以通过该类直接访问
类变量可以通过类的实例间接访问
类变量可以通过实例的__class__属性间接访问
示例:
class Animal():
type_num = 0
cat = Animal()
print(Animal.type_num)
print(cat.type_num) #这种方法得到的name只是其引用,只能对其操作,但是不能用=,=会更改绑定关系,相当为cat创建实例变量type_num
print(cat.__class__.type_num)
#预制的实例属性
__dict__属性:绑定一个存储此实例变量(属性)的字典
示例:cat = Cat()
cat.name = 'cat'
则cat.__dict__ 为 {'name':'dog'}
__class__属性:绑定创建此实例的类对象
实例:cat = Cat()
cat.name = 'cat'
则cat.__class__ 为 <class '__main__.Animal'>
作用:借助此属性创建同类对象(基本没用)
借助此属性访问类变量
__doc__属性:绑定文档字符串
__slots__列表:
作用:
1、限定一个类创建的实例只能由固定的实例变量
2、不允许对象添加此列表以外的实例属性
3、防止用户因写错属性名,引发错误
说明:
含有__slots__列表的类所创建的实例对象没有__dict__字典,即此实例不用字典来存储实例变量
class Student():
__slots__ = ["name", "age"]
s.name = 'asd' #对的
s.Name = 'asd' #报错
#关于类的系统内建函数
isinstance(obj, class_or_tuple) 返回该对象的obj是否是某个或者某些类其中的一个类创建的,如果是,返回True;否则返回Flase
type(obj):返回实例的类型
#类的类方法:仅属于类的方法,要用@classmethod来修饰;类方法只能访问类变量
第一个方法默认是类,约定为cls
说明:类和实例对象都能够调用类内的方法
类方法不能访问对象的实例变量
class A:
v = 0
@classmethod
def set_v(cls,value)
cls.v = value
A.set_v(100)
实例变量也可以创建同名的类变量,但是会为实例创建一个新变量
#静态方法:
用@staticmethod修饰器来修饰
不能传入self / cls, 只能定义在函数内部
类和实例都可以调用,不能访问类变量和实例变量
示例:
class A():
@staticmethod
def mymax(a,b):
return max(a,b)
A.max(10,11)
a = A()
a.max(999,1000)
相当于普通函数,但是只能通过类或者实例调用
也可以防止重名
#对象属性管理函数
getaddr(obj, name[, default]):getaddr(x, y, default)相当于获取x.y,如果不存在返回default,为给定default时,报错
hasaddr(obj, name):判断给定实例有没有该属性
setaddr(obj, name, value):设置obj.name = value
deladdr(obj, name):删除对象obj中的name属性,相当于del obj.name
#函数重写 overwrite
让自定义的类生成的对象(实例)能够像内建对象一样进行内建函数的操作
#重写str方法
使得str(obj)能够返回一个代表实例信息的字符串
示例:
class Student():
def __init__(self, n, a):
self.name = n
self.age = a
def __str__(self):
s = "%s is %d years old this year" % (self.name, self.age)
return s
a = Student("xiaozhang", 32)
print(a)
#或者str(a)
>>>xiaozhang is 32 years old this year
#repr & str
str(obj)将对象转换为字符串给人看
repr(obj)返回创建对象的表达式,可以用于远程传输对象
如果str对象没有重写,调用repr返回的结果
示例:
class Student():
def __init__(self, n, a):
self.name = n
self.age =a
def __str__(self):
s = "%s is %d years old this year" % (self.name ,self.age)
return s
def __repr__(self):
return "Student(%r, %d)" % (self.name, self.age)
#在repr重写时,用%r输出字符串
a = Student("xiaozhang", 32)
print(a)
print(str(a))
print(repr(a))
结果为:
xiaozhang is 32 years old this year
xiaozhang is 32 years old this year
Student(xiaozhang, 32)
#内建函数重写
__abs__ -> abs(obj)
__len__ -> len(obj)
__reversed__ -> reversed()
__round__ round(obj)
#不重写用不了
数值转换重写
__complex__
__int__
__float__
__bool__
#__bool__方法重写:
如果没有重写,将调用__len__方法;如果没有__len__方法,返回true
#高级迭代器
什么是迭代器:通过next(it)函数取值的对象就是迭代器
迭代器协议:指对象能够使用next函数取下一项数据,在没有下一项数据是出啊发StopIterable异常来终止迭代的约定
迭代器协议的实现方法:
在类中需要__next__(self)函数重写
代码:
class IntIterator():
def __init__(self, start_, stop_, step_ = 1):
self.start = start_
self.stop = stop_
if step_ == 0:
raise ValueError("step_ cannot be 0")
self.step = step_
def __next__(self):
if self.step < 0:
if self.start + self.step >= self.stop:
self.start += self.step
return self.start - self.step
raise StopIteration
if self.step > 0:
if self.start + self.step <= self.stop:
self.start += self.step
return self.start - self.step
raise StopIteration
it = IntIterator(1,13,1)
while True:
try:
print(next(it))
except:
break
#什么是可迭代对象:
用iter(obj)函数返回的对象
可迭代对象内部需要定义__iter__(obj)方法来返回迭代器对象
可迭代对象能用于for循环,而迭代器不能
可迭代对象的存在就是为了在for循环中方便的使用,for循环自动调用可迭代对象类中的__iter__()方法,然后用next函数获取迭代器下一个值,且产生StopIteration时不会触发异常
#示例代码:
class IntIterator():
def __init__(self, start_, stop_, step_ = 1):
self.start = start_
self.stop = stop_
if step_ == 0:
raise ValueError("step_ cannot be 0")
self.step = step_
def __next__(self):
if self.step < 0:
if self.start + self.step >= self.stop:
self.start += self.step
return self.start - self.step
raise StopIteration
if self.step > 0:
if self.start + self.step <= self.stop:
self.start += self.step
return self.start - self.step
raise StopIteration
class MyInteger():
def __init__(self, start_num, stop_num):
self.start = start_num
self.end = stop_num
def __iter__(self):
return IntIterator(self.start, self.end)
for x in MyInteger(10,20):
print(x)
前面的简单的yeild迭代器函数,会被转化为一个可迭代对象类
#异常(高级)
#with语句
with 表达式1 [as 变量1], 表达式2 [as 变量2] ...:
语句块
作用:用于对资源访问的场合,确保过程中是否发生错误都能够执行必要的资源释放工作
用处:常用于文件的打开和关闭,线程中锁的自动获取与释放
例子:with语句实现拷贝文件
def file_copy(src, dst):
with open(src, 'rb') as src_file, open(dst, 'wb') as dst_file:
data = src_file.read(1000)
if data == '':
return
dst_file.write(data)
import sys
if len(sys.argv) != 3:
raise ValueError("Script only takes and only takes 4 arguments")
file_copy(sys.argv[1], sys.argv[2])
#技巧:文本文件流文件也是一个可迭代对象,可以用
for x in file:
x代表一行
#环境管理器
1、有__enter__和__exit__方法的类所生成的对象叫做环境管理器
2、能够用with语句进行管理的对象必须是环境管理器
3、进入with语句时,自动调用__enter__()并将返回的对象给as的变量,所以__enter__()必须返回一个该类对象self;退出with语句时,自动调用__exit__()方法;
4、__exit__(self, exc_type, exc_value, exc_tb):当退出时自动调用
如果发生了异常,exc_type绑定异常类型,exc_value绑定对象
没有发生异常时,exc_type绑定None,exc_value绑定None
exc_tb绑定traceback 一般不用
示例:
class Cooker():
def doworks(self):
print("Doing work")
def open_gas(self):
print("Opening gas")
def close_gas(self):
print("Closing gas")
def __enter__(self):
self.open_gas()
return self
def __exit__(self, exc_type, exc_value, exc_tb):
self.close_gas()
with Cooker() as cook:
raise ValueError
#继承、派生
作用:
1、将类的公有功能实现在基类中,实现代码共享
2、不改变超类的代码的基础上,改变原有类的功能
#名词
基类(base class)= 超类(super class)= 父类(father class)
派生类(derived class) = 子类(child class)
#单继承语法
class class_name(父类):
...
#示例代码:
class Human():
def eat(self):
print("Eating")
def walk(self):
print("Walking")
class Student(Human):
def study(self ):
print("Studying")
def eat(self):
print("Student is eating")
s = Student()
s.eat()
s.study()
s.walk()
#将类的公有功能实现在基类中,实现代码共享:Student可以使用Human的方法
#不改变超类的代码的基础上,改变原有类的功能:Student重写了自己的eat方法,改变了父类的功能
#继承说明
一切类都继承自object类,object类是一切类的超类
#类的__base__属性:
记录该类的直系父类
#覆盖override
子类中重新定义父类中的方法,调用时调用重写后的方法,这种操作叫做覆盖,override