目录:
- 模块补充
- xml
- 面向对象
一、模块补充
shutil: 文件复制模块;进行文件copy、压缩; 使用方法: 将文件内容拷贝到另一个文件中,可以部分内容 shutil.copyfileobj(fsrc,fdst[,length]) #文件对象; 示例: 先打开文件再进行copy; import shutil f = open('example.log') f2 = open('example_new.log','w') shutil.copyfileobj(f,f2) shutil.copyfile(src, dst) 拷贝文件 直接copy文件名; shutil.copyfile(src,dst) shutil.copyfile('example_new.log','example_new2.log') shutil.copymode(str,dst) 仅拷贝权限,内容、用户和组均不变; shutil.copymode('example_new.log','example_new2.log') shutil.copystat(src, dst) 拷贝状态的信息,包括:mode bits, atime, mtime, flags shutil.copy(src, dst) 拷贝文件和权限 shutil.copy2(src, dst) 拷贝文件和状态信息 shutil.ignore_patterns(*patterns) shutil.copytree(src, dst, symlinks=False, ignore=None) 递归的去拷贝文件 例如:copytree(source, destination, ignore=ignore_patterns('*.pyc', 'tmp*')) shutil.rmtree(path[, ignore_errors[, onerror]]) 递归的去删除文件 shutil.move(src, dst) 递归的去移动文件 shutil.make_archive(base_name, format,...) 创建压缩包并返回文件路径,例如:zip、tar base_name: 压缩包的文件名,也可以是压缩包的路径。只是文件名时,则保存至当前目录,否则保存至指定路径, 如:www =>保存至当前路径 如:/Users/wupeiqi/www =>保存至/Users/wupeiqi/ format: 压缩包种类,“zip”, “tar”, “bztar”,“gztar” root_dir: 要压缩的文件夹路径(默认当前目录) owner: 用户,默认当前用户 group: 组,默认当前组 logger: 用于记录日志,通常是logging.Logger对象 示例: #将 /Users/wupeiqi/Downloads/test 下的文件打包放置当前程序目录 import shutil ret = shutil.make_archive("wwwwwwwwww", 'gztar', root_dir='/Users/wupeiqi/Downloads/test') #将 /Users/wupeiqi/Downloads/test 下的文件打包放置 /Users/wupeiqi/目录 import shutil ret = shutil.make_archive("/Users/wupeiqi/wwwwwwwwww", 'gztar', root_dir='/Users/wupeiqi/Downloads/test') 示例: import zipfile # 压缩 z = zipfile.ZipFile('laxi.zip', 'w') z.write('a.log') z.write('data.data') z.close() # 解压 z = zipfile.ZipFile('laxi.zip', 'r') z.extractall() z.close() 示例: import tarfile # 压缩 tar = tarfile.open('your.tar','w') tar.add('/Users/wupeiqi/PycharmProjects/bbs2.zip', arcname='bbs2.zip') tar.add('/Users/wupeiqi/PycharmProjects/cmdb.zip', arcname='cmdb.zip') tar.close() # 解压 tar = tarfile.open('your.tar','r') tar.extractall() # 可设置解压地址 tar.close() shutil 对压缩包的处理是调用 ZipFile 和 TarFile 两个模块来进行的,详细: 打包:文件名加日期可以自行拼接; shutil.make_archive('day5','zip','c:\\Users\Administrator\s16\day5') 跟json差不多,是实现不现语言或程序之间进行数据交换的协议; xml的格式如下,就是通过<>节点来区别数据结构的; <data> <country name="Liechtenstein"> <rank updated="yes">2</rank> <year>2008</year> <gdppc>141100</gdppc> <neighbor name="Austria" direction="E"/> <neighbor name="Switzerland" direction="W"/> </country> </data> xml的处理: xml协议在各个语言里的都是支持的,在python中可以用以下模块操作xml import xml.etree.ElementTree as ET tree = ET.parse('xmltest.xml') #解析 root = tree.getroot() print(root.tag) print(dir(root)) 遍历xml文档: for child in root: print(child tag,child.attrib) for i in child: print(i.tag,i.text,i.attrib) 只遍历year节点; for node in root.iter('year') print(node.tag, node.text) 只遍历country节点: for node in root.iter('year') print(node.tag, node.text, node.attrib) 修改: for node in root.iter('yesr'): new_year = int(node.text) + 1 node.text = str(new_year) node.set("updated","yes") tree.write("xmltest.xml") 删除node for country in root.findall('country'): rank = int(country.find('rank').text) if rank > 50: root.remove(country) tree.write('output.xml',encoding='utf-8') hashlib: hash加密模块;hmac模块:主要用于在互联网中的消息认证; 散列消息鉴别码,简称HMAC,是一种基于消息鉴别码MAC(Message Authentication Code)的鉴别机制。使用HMAC时,消息通讯的双方,通过验证消息中加入的鉴别密钥K来鉴别消息的真伪; 一般用于网络通信中消息加密,前提是双方先要约定好key,就像接头暗号一样,然后消息发送把用key把消息加密,接收方用key + 消息明文再加密,拿加密后的值 跟 发送者的相对比是否相等,这样就能验证消息的真实性,及发送者的合法性了。 subprocess: import subprocess subprocess.run(["df",'-h'],returncode=1) #自动拼接并输出; subprocess.run(["df","-h","|","grep","/dev/sda1"]) #有管道会报错; subprocess.run("df -h | grep /dev/sda1",shell=True) #shell=True表示直接调用shell,而不会解析 执行命令,返回命令执行状态,0 or 非0 subprocess.call("df -h | grep /dev/sda1",shell=True) 接收字符串格式命令,返回元组形式,第1个元素是执行状态,第2个是命令结果; ba = subprocess.getstatusoutput("df -h | grep /dev/sda1") run, shell=True call check_call getstatusoutput p = Popen() stdout = subprocess.PIPE, stderr = .... env = {} #后跟字典; cwd = {} prexec_fn = p.stdout.read() p.poll() p.wait() p.communicate(timeout=3) re: 正则表达式; re.match("al","alex li") #前面是规则,后面是要匹配的字串; <_sre.SRE_Match object; span=(0, 2), match='al'> a = re.match("^.+","alex\n li") a.group() #可打印匹配到的值; re.search("i$","alex\n li") re.match:从头开始匹配; re.search:匹配整行; re.findall('\W+','192.168.0.23') re.split('\W+','192.168.0.23') re.sub 匹配并替换; re.sub('\d{4}','1987','i was born in 1996-05-23,ys is 1919',count=1) #默认会全部替换;count指定替换多少次; 'i was born in 1987-05-23,ys is 1919' >>> re.search(r"\root\\","\root\\alex\test") <_sre.SRE_Match object; span=(0, 5), match='\root\\'> '.' 默认匹配除\n之外的任意一个字符,若指定flag DOTALL,则匹配任意字符,包括换行 '^' 匹配字符开头,若指定flags MULTILINE,这种也可以匹配上(r"^a","\nabc\neee",flags=re.MULTILINE) '$' 匹配字符结尾,或e.search("foo$","bfoo\nsdfsf",flags=re.MULTILINE).group()也可以 '*' 匹配*号前的字符0次或多次,re.findall("ab*","cabb3abcbbac") 结果为['abb', 'ab', 'a'] '+' 匹配前一个字符1次或多次,re.findall("ab+","ab+cd+abb+bba") 结果['ab', 'abb'] '?' 匹配前一个字符1次或0次 '{m}' 匹配前一个字符m次 '{n,m}' 匹配前一个字符n到m次,re.findall("ab{1,3}","abb abc abbcbbb") 结果'abb', 'ab', 'abb'] '|' 匹配|左或|右的字符,re.search("abc|ABC","ABCBabcCD").group() 结果'ABC' '(...)' 分组匹配,re.search("(abc){2}a(123|456)c", "abcabca456c").group() 结果 abcabca456c '\A' 只从字符开头匹配,re.search("\Aabc","alexabc") 是匹配不到的 '\Z' 匹配字符结尾,同$ '\d' 匹配数字0-9 '\D' 匹配非数字 '\w' 匹配[A-Za-z0-9] '\W' 匹配非[A-Za-z0-9] 's' 匹配空白字符、\t、\n、\r , re.search("\s+","ab\tc1\n3").group() 结果 '\t' '(?P<name>...)' 分组匹配 re.search("(?P<province>[0-9]{4})(?P<city>[0-9]{2})(?P<birthday>[0-9]{4})","371481199306143242").groupdict("city") 结果{'province': '3714', 'city': '81', 'birthday': '1993'}
三、面向对象
特性:封装、继承、多态
编程范式:
编程是程序员用特定的语法+数据结构+算法组成的代码来告诉计算机如何执行任务的过程;一个程序是程序员为了得到一个任务结果而编写的一组指令的集合;而实现一个任务的方式有很多种不同的方式,对这些不同的编程方式的特点进行归纳总结得出来的编程方式类别,即为编程范式;
大多数语言只支持一种编程范式,也有些语言也可以同时支持多种编程范式;两种最重要的编程范式分别是面向过程和面向对象编程;
面向过程:
面向过程编程依赖过程;一个过程包含一组要被进行计算的步骤,面向过程又被称为top-down languages;
面向对象:
OOP(object oriented programing)编程是利用"类"和"对象"来创建各种模型来实现对真实世界的描述;
面向对象的优点:
可以使程序的维护和扩展变得更简单;并且可以大大提高程序的开发效率;
基于面向对象的程序可以使他人更加容易理解代码逻辑;
Class类:
一个类即是对一类拥有相同属性的对象的抽象、蓝图、原型。在类中定义的这些对象的都具备的属性(variables(data))、共同的方法;
Object对象:
一个对象一个类的实例化后实例;一个类必须经过实例化后方可在程序中调用;一个类可以实例化多个对象,每个对象亦可以有不同的属性;
Encapsulation: 封装
在类中对数据的赋值、内部调用对外部用户是透明的,这使类变成了一个胶囊或容器,里面包含着类的数据和方法;
Inheritance: 继承
一个类可以派生出子类,在这个父类里定义的属性、方法自动被子类继承;
Polymorphism: 多态
python原生就是多态的;一个接口,多种实现;
示例: class Dog(object): age = 22 #类变量,存在类的内存地址里,可以被所有实例共享引用; def __init__(self,name,type): #初始化函数(构造函数) self.name = name # d.name = name self.type = type # d.type = type def balk(self): # self = d print('[%s] I am a dog!'%self.name) def eat(self,food): print("[%s] eating [%s]"%(self,name,food)) d = Dog("ys","zang ao") print(d.name, d.type) d.balk() d.eat('sandwish') d.name='ddd' print(d.name,d.age)
封装:
封装是面向对象的特征之一,是对象和类概念的主要特性;
类变量:
存在类的内存地址里,可以被所有实例共享引用;可以是一些共同属性;
作用:
作为默认公有属性;静态字段;
全局修改或增加新的属性;
示例: class People(object): nationality = "CN" def __init__(self,name,age,job): pass p = People("liuhao",22,'IT') p2 = People("yanshui",22,'IT') p.nationality = "JP" print(p.nationallity) p2.hobbie = "Big baojian" People.weapon = "Big baojian" #增加全局属性; print(p.weapon)
实例变量:(成员属性)
与类变量相反;构造函数里面的所有对象都是实例变量;
每个实例存在自己内存空间里的属性;
p2.hobbie = "Big baojian"
公有属性:==》 类变量;
私有属性:
不想被别人访问到的属性;
__sex: 表示私有属性,仅能在内部各函数(方法)中调用;
隐藏一些功能的实现细节,只给外部暴露调用接口;
继承:
面向对象编程(OOP)语言的一个主要功能就是继承,可以使用现有类的所有功能;并在无需重新编写原来的类的情况下对这些功能进行扩展;
通过继承创建的新类称为"子类"或"派生类";
被继承的类称为"基类"、"父类"或"超类";
继承的过程,就是从一般到特殊的过程;
继承的实现两种方式:
继承
组合
在有些OOP语言中,一个子类可以继承多个基类,一般情况下,一个子类只能有一个基类,要实现多重继承,可以通过多级继承来实现;
继承概念的实现方式主要有2类:
实现继承
是指使用基类的属性和方法而无需额外编码的能力;
注意:两个类之间的关系应该是"属于"关系;
接口继承
是指仅使用属性和方法的名称,但是子类必须提供实现的能力(子类重构父类的方法);
抽象类就是父类,仅定义由子类创建的一般属性和方法;
示例: class SchoolMember(object): members = 0 def __init__(self,name,age,sex): self.name = name self.age = age self.sex = sex SchoolMember.members += 1 print("初始化了一个新学校成员",self.name) def tell(self): info = """ ------info of %s --------- name: %s age: %s sex:%s """%(self.name,self.name.self.age,self.sex) print(info) def __del__(self): #析构方法: print("%s 被开除了"%self.name) SchoolMember.members -= 1 class Teacher(SchoolMember): #继承 def __init__(self,name,age,sex,salary): #手动调用父类方法; SchoolMember.__init__(self,name,age,sex,salary) #self.name = name #self.age = age #self.sex = sex self.salary = salary def teaching(self,course): print("%s is teaching %s"%(self.name,self.course)) class Student(SchoolMember): def __init__(self,name,age,sex,grande) SchoolMember.__init__(self,name,age,sex,grande) self.grande = grande def pay_tuition(self,amount): self.paid_tuition = amount print('stduent %s has paid tutuion amount %s'%(self.name,amount)) t = Teacher("Alex",22,"F",3000) s = Student("liuhao",24,"M","pays16") s1 = Student("yanshuai",46,"F","pys26") s2 = Student('Nining',32,'F','pys26') del s2 #删除一个实例; t.tell() s.tell() s1.tell() t.teaching("python") s.pay_tuition(11000) print(t.name) print(t.age) print(t.salary) print(SchoolMember.members)
继承:
1、直接调用父类方法;
2、继承父类方法并重构父类方法,先重构,再重构的方法里手动调用父类方法;
3、可以定义子类自己的方法;
4、析构方法;
多继承:
一般最多继承两个;
示例: class Course(object): course_name = "Python 自动化" period = "7m" outline = "sfdskljjklfsdj" test = 321 class Student(SchoolMember,Course,my_teacher): test = 123 def __init__(self,name,age,sex,grande) SchoolMember.__init__(self,name,age,sex,grande) self.grande = grande self.my_teacher =teacher def pay_tuition(self,amount): self.paid_tuition = amount print('stduent %s has paid tutuion amount %s'%(self.name,amount)) c = Course() #可达到构造函数效果; c.name = "Linux" s = Student("liuhao",24,"M","pays16",t) s.my_new_teacher = t print(s.course_name, s.outline) print(s.test) print("my teacher",s.my_teacher.name)