第七章:Python面向对象编程+常用模块

 大纲:  

  常用模块

    xml模块

              configparser模块

              hashlib模块

              subprocess模块

  面向对象介绍与类

    对象

    属性查找

    继承

    组合

    子类调用父类的方法super

    绑定方法与非绑定方法

一、xml模块

xml是实现不同语言或程序之间进行数据交换的协议,跟json差不多,但json使用起来更简单,不过,古时候,在json还没诞生的黑暗年代,大家只能选择用xml呀,至今很多传统公司如金融行业的很多系统的接口还主要是xml。

xml的格式如下,就是通过<>节点来区别数据结构的:

<?xml version="1.0"?>
<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>
    <country name="Singapore">
        <rank updated="yes">5</rank>
        <year>2011</year>
        <gdppc>59900</gdppc>
        <neighbor name="Malaysia" direction="N"/>
    </country>
    <country name="Panama">
        <rank updated="yes">69</rank>
        <year>2011</year>
        <gdppc>13600</gdppc>
        <neighbor name="Costa Rica" direction="W"/>
        <neighbor name="Colombia" direction="E"/>
    </country>
</data>
文件 a.xml

xml协议在各个语言里的都 是支持的,在python中可以用以下模块操作xml:

import  xml.etree.cElementTree as et
tree=et.parse('a.xml') #使用et来解析
root=tree.getroot()  #拿到tree的根节点
#
# for i in root:  #拿到每个contry
#     print('==>%s',i.tag)
#     for j in i:  #拿到每个contry下的子节点
#         print(j.tag,j.attrib,j.text)
'''
xml需要记住3个属性:标签名字、属性、内容
'''
#查找element的3中方式
# i=root.iter('year')  #扫描找个xml,找到索引
# for iter in i:
#     print(iter)

# res=root.find('country') #谁来掉,就从谁的下一层开始找,只找一个
# print(res)
#
# res=root.findall('country') #谁来掉,就从谁的下一层开始找,所有的
# print(res)

#修改文件
# years=root.iter('year')
# for year in years:
#     year=int(year.text)+1   #把所有的year的值加一
#     print(year)
# tree.write('b.xml')  #写入新文件b.xml’

#删除,删除rank里面大于10的东西
# for couty in root:
#     print(couty.tag)
#     rank=couty.find('rank')
#     if int(rank.text) >10:
#         couty.remove(rank)
# tree.write('b.xml')

#添加节点
for couty in root.findall('country'):
    e=et.Element('sheng')
    e.text='LeLe'
    e.attrib={'lele':'18'}
    couty.append(e)
tree.write('c.xml')

 

二、configparser模块

解析置文件:配置文件如下:

[egon]
name = egon
is_admin = True
salary = 3.1
age=123

[alex]
name = SB

[ShengLeQi]
name=shengleqi
ip=127.0.0.1
hsotname=shengleqi
View Code

configparser操作:

import configparser

config=configparser.ConfigParser()
config.read('a.ini')

#取配置
print(config.sections()) #看标题
print(config.options(config.sections()[0]))  #查看第一个标题下的key值

# print(config.get('ShengLeQi','name'))  #c查看某个标题下面的名字(值)
# res=config.getint('egon','age')  #直接拿到age的整形类型
    # config.getboolean()  #布尔值
    # config.getfloat() #浮点型

# print(type(res))

#修改
config.remove_section('ShengLeQi')  #删除标题‘ShengLeQi’
config.remove_option('alex','name')  #删除标题'alex'下的name

config.write(open('a.ini','w'))  #写入文件

三、 hashlib模块

hash:一种算法 ,3.x里代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法
三个特点:
     1.内容相同则hash运算结果相同,内容稍微改变则hash值则变
     2.不可逆推
     3.相同算法:无论校验多长的数据,得到的哈希值长度固定。

import hashlib

#一行行读取不消耗内存(推介)
m=hashlib.md5('h'.encode('utf-8'))
m.update('elloworld'.encode('utf-8'))
print(m.hexdigest())
m=hashlib.md5()
with open('a.xml','rb') as f:
    for line in f:
        m.update(line)
print(m.hexdigest())

# #耗费内存不推荐使用
m=hashlib.md5()
with open('a.xml','rb') as f:
    m.update(f.read())
print(m.hexdigest())

#加盐,为什么放在内容的泄露
password='alex3714'
m=hashlib.md5('yihangbailushangqingtian'.encode('utf-8'))
m.update(password.encode('utf-8'))
passwd_md5=m.hexdigest()

print(passwd_md5)

#hmac模块
#好md5不一样的地方是只要初始值不一样hmac出来的值就不一样。
import hmac
h=hmac.new('hello'.encode('utf-8'))
h.update('world'.encode('utf-8'))
print(h.hexdigest())

h=hmac.new('hello'.encode('utf-8'))
h.update('w'.encode('utf-8'))
h.update('or'.encode('utf-8'))
h.update('ld'.encode('utf-8'))
print(h.hexdigest())

四、subprocess模块

  运行python的时候,我们都是在创建并运行一个进程。像Linux进程那样,一个进程可以fork一个子进程,并让这个子进程exec另外一个程序。在Python中,我们通过标准库中的subprocess包来fork一个子进程,并运行一个外部的程序。
    subprocess包中定义有数个创建子进程的函数,这些函数分别以不同的方式创建子进程,所以我们可以根据需要来从中选取一个使用。另外subprocess还提供了一些管理标准流(standard stream)和管道(pipe)的工具,从而在进程间使用文本通信。

import subprocess
res=subprocess.Popen(r'dir C:\Users\think\PycharmProjects\Python18\day07',
                     shell=True,
                     stdout=subprocess.PIPE,
                     stderr=subprocess.PIPE
                     ) #执行命令
print('=========>%s'%res)
print(res.stdout.read().decode('gbk')) #Linux下utf-8
print(res.stdout.read().decode('gbk')) #Linux下utf-8

#dir file_path | findstr xml$
res1=subprocess.Popen(r'dir C:\Users\think\PycharmProjects\Python18\day07',
                     shell=True,
                     stdout=subprocess.PIPE,)

# stdin=res1.stout
res2=subprocess.Popen(r'findstr xml$',
                     shell=True,
                     stdin=res1.stdout,
                     stdout=subprocess.PIPE,)

print(res2.stdout.read().decode('gbk')) 

五、面向对象

面向对象介绍

'''

面向过程:核心是过程二字,过程指的是问题的解决步骤,即先干什么再干什么,基于

面向过程去设计程序就好比在设计一条流水线,是一种机械式的思维方式

优点:复杂的问题流程化,进而简单化

缺点:可扩展性差

应用:脚本程序,比如linux系统管理脚本,著名案例:linux内核,httpd,git 

面向对象:核心是对象二字,对象就是特征与技能的结合体,如果把设计程序比喻成

创造一个世界,那你就是这个世界的上帝,与面向过程对机械流水的模拟形式鲜明的对比

面向对象更加注重的对现实时间的模拟。 

优点:可扩展性

缺点: 

类即种类,类别,对象是特征和与技能的结合体,那么类就是一系列对象相似的

特征与技能的结合体

在现实世界中:先有一个个具体存在的对象----》(总结相似之处)---》现实中的类

在程序中:一定是先定义类,后调用类来产生对象 

#第一阶段:现实中的对象----》现实中类

# 产生程序中的对象:类名加括号,调用类,产生一个该类的实际存在的对象,该调用过程称为实例化,产生的结果又可以成为实例

class OldboyStudent:
    school = 'oldboy'
    def __init__(self,name,age,sex): #在实例化时,产生对象之后执行
        # if not isinstance(name,str):
        #     raise TypeError('名字必须是字符串类型')
        self.name=name
        self.age=age
        self.sex=sex
#实例化
obj1=OldboyStudent('李大炮',18,'') #
# 分两步:
# 第一步:先产生一个空对象obj1
# 第二步:OldboyStudent.__init__(obj1,'李大炮',18,'女')
print(obj1.__dict__)
#1、__init__必须返回None

六、属性查找

class OldboyStudent:
    school = 'oldboy'

    def __init__(self,name,age,sex):
        self.name=name
        self.age=age
        self.sex=sex
    def learn(self):
        print('%s is learning'  %self.name)
    def eat(self):
        print('is eating')

obj1=OldboyStudent('李大炮',18,'')
obj2=OldboyStudent('张全蛋',28,'')
obj3=OldboyStudent('牛榴弹',18,'')
print(obj1.school,id(obj1.school))
print(obj2.school,id(obj2.school))
print(obj3.school,id(obj3.school))
print(OldboyStudent.school,id(OldboyStudent.school))
# oldboy 36803336
# oldboy 36803336
# oldboy 36803336
# oldboy 36803336
#都是同一个oldboy,地址也是一样指向同一块内存地址
# 对象可以访问类的数据属性,结论:类的数据属性共享给所有对象使用,id对一样

#类的函数属性
OldboyStudent.learn(obj1)
OldboyStudent.learn(obj2)
# 李大炮 is learning
# 张全蛋 is learning


#对象函数属性
#绑定方法,谁来调用就把谁当成第一个参数传入
obj1.learn()  #OldboyStudent.learn(obj1)
obj2.learn()  #OldboyStudent.learn(obj12)
# 李大炮 is learning
# 张全蛋 is learning
View Code

小练习

1、计算一共初始化多少个实例?

class Foo:
    count=0
    def __init__(self,x,y,z):
        self.x=x
        self.y=y
        self.z=z
        Foo.count+=1
obj1=Foo(1,1,1)
obj2=Foo(1,2,1)
obj3=Foo(1,2,3)
print(Foo.count)

七、继承

类的继承

       继承是什么是什么的关系。

面向对象的编程带来的主要好处之一是代码的重用,实现这种重用的方法之一是通过继承机制。继承完全可以理解成类之间的类型和子类型关系。

需要注意的地方:继承语法 class 派生类名(基类名)://... 基类名写作括号里,基本类是在类定义的时候,在元组之中指明的。

在python中继承中的一些特点:

1:在继承中基类的构造(__init__()方法)不会被自动调用,它需要在其派生类的构造中亲自专门调用。使用super().__init__()或parentClassName.__init__()

2:在调用基类的方法时,需要加上基类的类名前缀,且需要带上self参数变量。区别于在类中调用普通函数时并不需要带上self参数

3:Python总是首先查找对应类型的方法,如果它不能在派生类中找到对应的方法,它才开始到基类中逐个查找。(先在本类中查找调用的方法,找不到才去基类中找)。

如果在继承元组中列了一个以上的类,那么它就被称作"多重继承" 。

# 继承的基本形式

class ParentClass1(object): #定义父类
    pass
class ParentClass2: #定义父类
    pass
class SubClass1(ParentClass1): #单继承,基类是ParentClass1,派生类是SubClass
    pass
class SubClass2(ParentClass1,ParentClass2): #python支持多继承,用逗号分隔开多个继承的类
    pass
print(SubClass1.__bases__)
print(SubClass2.__bases__)
print(ParentClass1.__bases__)

#子类继承父类并且有自己的属性

class Animal:
    def __init__(self,name,age,sex):
        self.name=name
        self.age=age
        self.sex=sex
        # print('Animal.__init__')
    def eat(self):
        print('%s eat' %self.name)
    def talk(self):
        print('%s say' %self.name)
class People(Animal):
    def __init__(self,name,age,sex,education):
        Animal.__init__(self,name,age,sex)
        self.education=education
        # print('People.__init__')
    def talk(self):
        Animal.talk(self)   #直接调用 类的方法talk
        print('这是人在说话')
Sheng=People('ShengLeQi',18,'man','中学')
Sheng.talk()
View Code

继承功能:解决类与类的代码重用功能

class OldboyPeople:
    school = 'oldboy'
    def __init__(self,name,age,sex):
        self.name=name
        self.age=age
        self.sex=sex
    def eat(self):
        print('is eating')
class OldboyStudent(OldboyPeople):
    def learn(self):
        print('%s is learning'  %self.name)
class OldboyTeacher(OldboyPeople):
    def __init__(self,name,age,sex,salary,title):
        OldboyPeople.__init__(self,name,age,sex)  #继承OldboyPeople的属性
        self.salary=salary
        self.title=title
    def teach(self):
        print('%s is teaching'  %self.name)
s_obj=OldboyStudent('sheng',28,'female')
e_obj=OldboyTeacher('egg',18,'male',3.1,'沙河霸道金牌讲师')
s_obj.learn()
e_obj.eat()
View Code

'''
继承功能:
1、继承功能:解决类与类的代码重用功能
2、继承是类与类的关系,是一种什么是什么的关系
3、在子类派生出的新的属性,以自己为追准
4、在子类派生出的新的方法内重用父类的功能的方式:指明道姓法。
OldboyPeople.__init__
这种调用关系本身是没有继承管
'''

继承super

super是基于继承后子类调用服父类的方法。根据mro()来找知己的父类。

class people():
    def __init__(self,name,age):
        self.name=name
        self.age=age
    def cat_show(self):
        print('这个是父类的。。')

class Sheng(people):
    def __init__(self,name,age,job):
        super().__init__(name,age)  #在子类中重用父类的方法(需要有继承关系)
        self.job=job
    def show(self):
        super().cat_show()

SLQ=Sheng('shengleqi',18,'yunwei')
SLQ.show()

 

八、组合

     继承:是什么是什么的关系

     组合:是什么有什么的组合

class OldboyPeople:
    school = 'oldboy'
    def __init__(self,name,age,sex):
        self.name=name
        self.age=age
        self.sex=sex
    def eat(self):
        print('is eating')
class OldboyStudent(OldboyPeople):
    def __init__(self,name,age,sex):
        OldboyPeople.__init__(self,name,age,sex)
        self.course=[]

    def learn(self):
        print('%s is learning'  %self.name)

class OldboyTeacher(OldboyPeople):
    def __init__(self,name,age,sex,salary,title):
        OldboyPeople.__init__(self,name,age,sex)
        self.salary=salary
        self.title=title
        self.course=[]
    def teach(self):
        print('%s is teaching'  %self.name)

class Course:
    def __init__(self,course_name,course_period,course_price):
        self.course_name=course_name
        self.course_period=course_period
        self.course_price=course_price
    def tell_info(self):
        print('<课程名:%s 周期:%s 价格:%s>' %(self.course_name,self.course_period,self.course_price))

python=Course('Python','6mons',3000)
linux=Course('Lnux','3mons',2000)
bigdata=Course('BigData','1mons',1000)

# python.tell_info()

egon_obj=OldboyTeacher('egon',18,'male',3.1,'沙河霸道金牌讲师')
#
# egon_obj.course.append(python)
# egon_obj.course.append(linux)
#
# for obj in egon_obj.course:
#     obj.tell_info()

yl_obj=OldboyStudent('yanglei',28,'female')
yl_obj.course.append(python)

for i in yl_obj.course:
    # print(i.course_name,i.course_period,i.course_price)
    i.tell_info()

十、绑定方法与非绑定方法

'''
绑定给谁就是给谁来用的,谁来用的就会把自己自动传值。
'''

import settings
class MySql:
    def __init__(self,host,port):
        self.host=host
        self.port=port
    @classmethod
    def from_conf(cls):
        # print(cls)
        return cls(settings.HOST,settings.PORT)
    def func1(self):pass

conn1=MySql('127.0.0.1',3306)

#对象和类都可以调用from_conf,传入的参数还是cls
conn1.from_conf()
MySql.from_conf()

'''
绑定给谁就是给谁来用的,谁来用的就会把自己自动传值。
'''

# @classmethod
# def from_conf(cls): #绑定给类的
#     print(cls)
#     # return cls(settings.HOST,settings.PORT)
#
# def func1(self): #绑定给对象的
#     pass

 

posted @ 2017-08-16 11:59  ShengLeQi  阅读(181)  评论(0)    收藏  举报