python模块、面向对象编程

时间:2023-02-15 14:37:54

目录:

  • 模块补充
  • 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)