• oop、configparser、xml模块


    本节大纲:

    一:在python中,有两种编程思想。1:函数式编程。2:oop。无论是函数式编程还是oop都是相辅相成。并不是说oop比函数式编程就好。各有各的优缺点。
    在其他语言中java等只能以面向对象进行编程。
    函数放在类中叫做方法。
    只有对象才能调用类中的方法,也就是说需要创建该类的对象然后调用该类的方法。
    而函数调用直接进行调用。

    类需要创建对象,通过对象调用执行类中的方法。而函数可以直接进行调用,无需创建对象。

    1:创建对象:和函数式调用雷同:类名()

    obj=coo()

    2:通过对象执行类中的方法.对象和属性用圆句点(.)进行连接。

    obj.co()

    二:定义类的语法:

    a:class  类名:

          def 方法名(self,x)

            passs

    关键字:class ,然后跟着类名。任何函数在类中都叫方法。方法的第一个参数必须是self。在构造对象的时候,会自动把对象名字传给self。类中的方法只能是对象来调用。

    b:对象创建:

    对象名=类名()

    c:通过对象来执行类中的方法。

    三:类和对象的关系

    在创建对象的时候,在对象的内部有一个类对象指针指向自己的类。当对象执行check()方法的时候,根据类指针找到自己的类sql中的方法check进行执行。并把对象obj当做实参传给方法check的self形参。

    并不是对象有该方法。

    四:在什么情况下使用面向对象?

    需求:对数据库的增删改查操作

    a:函数式编程

     1 #!/usr/bin/env python
     2 def check(host,user,pwd,sql):
     3     pass
     4 def  add(host,user,pwd,sql):
     5     pass
     6 def delete(host,user,pwd,sql):
     7     pass
     8 def update(host,user,pwd,sql):
     9     pass 
    10 check('1.1.1.1','evil','123','....')
    11 add('1.1.1.1','evil','123','....')
    12 delete('1.1.1.1','evil','123','....')
    13 update('1.1.1.1','evil','123','....')

    没调用都需要传入,host、user、pwd、sql参数。如果操作数据库的动作较多,会反复传入多次。

    面向对象编程:

     1 class sql:
     2     def check(self,sql):
     3         print(self.host)
     4         print(self.user)
     5         print(self.password)
     6     def crate(self,sql):
     7         pass
     8     def update(self,sql):
     9         pass
    10     def delete(self,sql):
    11         pass
    12 
    13 obj=sql()
    14 obj.host='1,1,1,1'
    15 obj.user='evil'
    16 obj.password='123'
    17 obj.check("select * from A")
    18 1,1,1,1
    19 evil
    20 123

    当我们执行相关操作的时候,我们只需要把数据封装到对象里,在调用类的方法的时候,自动获取对象的属性值,即可连接到数据库。而不需要每次都需要把账号、主机、密码都传入方法中进行操作。

    什么时候用面向对象呢?

    当某一些函数中有相同的参数的时候,可以用面向对象的封装特性,将参数值一次性的封装到对象,之后执行该对象的类的方法的时候不需要每次传入对应的参数。每次执行类的方法的时候,只需要从对象中取值即可。

     五:self参数。

    self 是python自动传值的形式参数。

    当对象调用类的方法的时候,会自动把对象的赋值给self形式参数。

    当obj调用类的方法check时候,self会自动赋值为obj,当obj1调用类sql的方法check时候,self会自动赋值obj1。

    也就是说可以通过创建不通的对象来实现连接不通的数据库。

    六:构造方法__init__

    当执行类名()时候会自动执行类中的方法:__init__方法。

     1 class sql:
     2     def __init__(self):
     3         print('__init__')
     4     def check(self,sql):
     5         print(self.host)
     6         print(self.user)
     7         print(self.password)
     8     def crate(self,sql):
     9         pass
    10     def update(self,sql):
    11         pass
    12     def delete(self,sql):
    13         pass
    14 
    15 obj=sql()
    16 __init__

    也就是说当执行对象创建的时候,也就是执行sql()的时候,会自动执行__init__方法。

    根据这个特性,我们以后将对象封装的数据,方法__init__方法中。

     1 class sql:
     2     def __init__(self,a,b,c):
     3         self.host=a
     4         self.user=b
     5         self.password=c
     6     def check(self,sql):
     7         print(self.host)
     8         print(self.user)
     9         print(self.password)
    10     def crate(self,sql):
    11         pass
    12     def update(self,sql):
    13         pass
    14     def delete(self,sql):
    15         pass
    16 
    17 obj=sql('1.1.1.1','evil','123')
    18 obj.check('selec.....')
    19 
    20 1.1.1.1
    21 evil
    22 123

    通过对象创建的时候,对__init__方法的参数进行实参的传入。

    __init__方法叫做构造方法。构造对象的方法。

    七:调用顺序

    函数调用的时候,需要先声明函数,才能进行调用,而在类中,没有这个上下顺序,可以在方法声明前进行调用。

     1 class sql:
     2     def __init__(self,a,b,c,d):
     3         self.host=a
     4         self.user=b
     5         self.password=c
     6         self.check(d)
     7     def check(self,sql):
     8         print(self.host)
     9         print(self.user)
    10         print(self.password)
    11         print(sql)
    12     def crate(self,sql):
    13         pass
    14     def update(self,sql):
    15         pass
    16     def delete(self,sql):
    17         pass
    18 
    19 obj=sql('1.1.1.1','evil','123','check')
    20 1.1.1.1
    21 evil
    22 123
    23 check

    其中self.check(d)相当于obj.check('check')只不过是在构造方法执行的时候调用这个函数。

    八:封装

     1 class game_life:
     2     def __init__(self,name,age,fight):
     3         self.name=name
     4         self.age=age
     5         self.fight=fight
     6     def battle_row(self):
     7         self.fight=self.fight-200
     8     def study(self):
     9         self.fight=self.fight+100
    10     def person_game(self):
    11         self.fight=self.fight-500
    12 
    13 
    14 obj=game_life('苍井井','18',1000)
    15 obj.battle_row()
    16 print(obj.fight)
    17 800

    也就说 可以通过类的方法对类的对象的值进行修改。

    面向对象三大特性:封装、继承、多太。

    封装:将数据通过__init__方法封装到对象中。供方法进行调用和操作。

    九:封装的对象可以数据,也可以是对象,可以任意东西。

     1 class a:
     2     def __init__(self,name,age):
     3         self.name=name
     4         self.age=age
     5     def show(self):
     6         print(self.name)
     7 class b:
     8     def __init__(self,name,obj):
     9         self.name=name
    10         self.obj=obj
    11 
    12 obj_a=a('evil',18)
    13 obj_b=b('tom',obj_a)
    14 print(obj_b.obj.name)
    15 print(obj_b.obj.age)
    16 evil
    17 18

    也就是对象ojb封装的是name和对象obj_a.也就是说封装可以是数据,也可以是对象,也可以是任意事物。

     1 class a:
     2     def __init__(self,name,age):
     3         self.name=name
     4         self.age=age
     5     def show(self):
     6         print(self.name)
     7 class b:
     8     def __init__(self,name,obj):
     9         self.name=name
    10         self.obj=obj
    11 class c:
    12     def __init__(self,name,a):
    13         self.name=name
    14         self.a=a
    15 
    16 obj_a=a('evil',18)
    17 obj_b=b('tom',obj_a)
    18 obj_c=c('jack',obj_b)
    19 print(obj_c.a.obj.name)
    20 obj_c.a.obj.show()
    21 
    22 evil
    23 evil
    res=obj_c.a.obj.show()
    print(res)

     注意show方法没有返回值,所以res值是None.

    也就是通过obj_c怎么访问obj_a.show()或者obj_a.name?

    如上图所示obj_c.a是obj_b对象,而obj_b.obj对象是obj_a对象,obj_a.name  obj_a.show()是我们想要的结果。

    所以:obj_c.a.obj.name   obj_c.a.obj.show()

    十:继承

    在其他语言里java里只有单继承,而在python 中可以有多继承。语法:

    1 class a:
    2     def show(self):
    3         print('show')
    4 class b(a):
    5     def co(self):
    6         print('co')
    7 obj=b()
    8 obj.show()
    9 show

    也就是在类名后面加个(继承类的类名)即可。也就是说a相当于与b是父类,b相对于a是子类,或者说a是基类,b是派生类。注意说法,各自对应。谁是父类,谁是子类只是相对而言。子类可以继承父类的方法。父类不可以继承子类的方法。

    如上,当对象obj调用方法show的时候,优先看自己类中是否有该方法,如果有就执行,不去父类找该方法。如果该方法没有的话去找他的父类是否有该方法。如果有就执行。

     1 class a:
     2     def show(self):
     3         print('show')
     4 class b(a):
     5     def co(self):
     6         print('co')
     7     def show(self):
     8         print('b')
     9 obj=b()
    10 obj.show()
    11 b

     继承的本质:子类没有的方法,方法在父类里,在对象调用该方法的时候,相当于父类的方法拿到子类的中。如下:

     1 class a:
     2     def __init__(self,name):
     3         self.name=name
     4     def show(self):
     5         print(self.name)
     6 class b(a):
     7     def __init__(self,name):
     8         self.name=name
     9     def co(self):
    10         print('co')
    11 obj=b('tom')
    12 obj1=a('evil')
    13 obj.show()
    14 tom

     也就是说子类对象obj在调用父类show方法的时候,传入的self.name是子类的self.name。也就是说相当于把父类的方法show拿到子类中。

    如上所示:对象obj在执行方法show时候优先去子类b中找show方法,如果子类没有show方法的话,去父类的a中找show方法,并执行show方法,show方法

    相当于拿到子类b中,因为子类b在构造对象obj的时候,已经封装数据self.name=name,所以获取的是子类的b的对象数据,也就是tom。而不是父类a的self.name属性。

     1 class a:
     2     def s1(self):
     3         print(a)
     4     def s2(self):
     5         self.s1()
     6 class b(a):
     7     def s1(self):
     8         print('b')
     9     def s3(self):
    10         self.s2()
    11 
    12 obj=b()
    13 obj.s3()
    14 b

     继承优先级:如果子类继承父类,对象在调用方法的时候,优先子类中找,如果有该方法执行该方法,如果没有在去父类找该方法。本质是:把父类的该方法拿到子类中,进行调用执行。

    继承优先执行子类的中方法,如果子类中有该方法执行子类方法。

    另一个思路:在执行self.xx的时候需要注意self是指执行对象,需要去执行对象的类型中去找,如果没有,再去父类找。

    十一:多继承(python3中)

     1 class a:
     2     def f2(self):
     3         print('class a')
     4 class b:
     5     def f2(self):
     6         print('class b')
     7 class c(a,b):
     8     def f3(self):
     9         pass
    10 obj=c()
    11 obj.f2()
    12 class a

     多继承的时候,优先从左有到右。如上classc(a,b)子类c中没有方法f2,在去父类a,b中找,优先顺序 a  然后是b。从左到右顺序。

    没有父类交叉的情况:

     1 class s1:
     2     def f1(self):
     3         print('s1')
     4 class s2(s1):
     5     def f2(self):
     6         print('s2')
     7 class s3:
     8     def f1(self):
     9         print('s3')
    10 class s4(s2,s3):
    11     def f2(self):
    12         print('s4')
    13 obj=s4()
    14 obj.f1()
    15 s1

    当有纵向和横向的多继承时候,顺序:首先按继承顺序,从左到右优先级,先从对象的类中找,如果没有按对象类型的父类(从左右)中找,如果没有,去他的父类的父类中找,如果最后

    没有的话,在找下一个对象的类父类平行的中父类中找,按照之前如果没有在去父类的父类找。。 如果没有在回到对象的类的平行父类中。。

     父类有交叉的情况:

     1 class s_1:
     2     def f2(self):
     3         print('s_1')
     4 class s0(s_1):
     5     def f2(self):
     6         print('s0')
     7 class s1(s_1):
     8     def f1(self):
     9         print('s1')
    10 class s2(s1):
    11     def f1(self):
    12         print('s2')
    13 class s3(s0):
    14     def f1(self):
    15         print('s3')
    16 class s4(s2,s3):
    17     def f1(self):
    18         print('s4')
    19 obj=s4()
    20 obj.f2()
    21 
    22 s0

    优先没交集的父类,当这个2个都遍历照完之后在找交集部分,在去平行的父类找也就是第7步。代码如下:

     1 class s_1:
     2     def f1(self):
     3         print('s_1')
     4 class s0(s_1):
     5     def f1(self):
     6         print('s0')
     7 class s1(s_1):
     8     def f1(self):
     9         print('s1')
    10 class s2(s1):
    11     def f1(self):
    12         print('s2')
    13 class s3(s0):
    14     def f1(self):
    15         print('s3')
    16 class s5:
    17     def f2(self):
    18         print('s5')
    19 class s4(s2,s3,s5):
    20     def f1(self):
    21         print('s4')
    22 obj=s4()
    23 obj.f2()
    24 s5

     关于__init__构造方法:当对象创建的时候,会自动去自己类中找__init__构造方法,如果没有去父类找。如果有的话执行__init__方法。如果都没有就不执行该方法。

     1 class s1:
     2     def __init__(self,name):
     3         self.name=name
     4     def show(self):
     5         pass
     6 class s2(s1):
     7     def look(self):
     8         pass
     9 
    10 
    11 obj=s2('evil')
    12 print(obj.name)
    13 evil

    查找顺序和 多继承顺序是一样的。

     模块:configparser 针对特殊配置文件进行操作。其本事是对文件的open()操作。

    如下:

    1 [section1] # 节点
    2 k1 = v1    # 值
    3 k2:v2       # 值
    4  
    5 [section2] # 节点
    6 k1 = v1    # 值

      操作:获取所有节点

    1 import  configparser
    2 
    3 con=configparser.ConfigParser()
    4 con.read('1.txt',encoding='utf-8')
    5 res=con.sections()
    6 print(res)
    ['section1', 'section2']

    获取指定节点下的key和值

    1 import  configparser
    2 
    3 con=configparser.ConfigParser()
    4 con.read('1.txt',encoding='utf-8')
    5 res=con.items('section1')
    6 print(res)
    7 [('k1', 'v1'), ('k2', 'v2')]

     获取指定节点下的键值

    1 import  configparser
    2 
    3 con=configparser.ConfigParser()
    4 con.read('1.txt',encoding='utf-8')
    5 res=con.options('section1')
    6 print(res)
    7 ['k1', 'k2']

     获取指定节点指定值

    1 import  configparser
    2 
    3 con=configparser.ConfigParser()
    4 con.read('1.txt',encoding='utf-8')
    5 res=con.get('section1','k1')
    6 print(res)
    7 v1
     1 import  configparser
     2 
     3 con=configparser.ConfigParser()
     4 con.read('1.txt',encoding='utf-8')
     5 has_sec = con.has_section('section1')
     6 print(has_sec)
     7 
     8 # 添加节点
     9 con.add_section("sec_1")
    10 con.write(open('1.txt', 'w'))
    11 
    12 # 删除节点
    13 con.remove_section("sec_1")
    14 con.write(open('1.txt', 'w'))
    XML模块
    xml是实现不同语言或程序之间进行数据交换的协议
    格式如下:
     1 <data>
     2     <country name="Liechtenstein">
     3         <rank updated="yes">2</rank>
     4         <year>2023</year>
     5         <gdppc>141100</gdppc>
     6         <neighbor direction="E" name="Austria" />
     7         <neighbor direction="W" name="Switzerland" />
     8     </country>
     9     <country name="Singapore">
    10         <rank updated="yes">5</rank>
    11         <year>2026</year>
    12         <gdppc>59900</gdppc>
    13         <neighbor direction="N" name="Malaysia" />
    14     </country>
    15     <country name="Panama">
    16         <rank updated="yes">69</rank>
    17         <year>2026</year>
    18         <gdppc>13600</gdppc>
    19         <neighbor direction="W" name="Costa Rica" />
    20         <neighbor direction="E" name="Colombia" />
    21     </country>
    22 </data>

     解析xml文件

    1 from xml.etree import ElementTree as E
    2 str_xml = open('1.xml', 'r').read()# 打开文件,读取包含xml文件内容
    3 root = E.XML(str_xml)# 将字符串解析成xml特殊对象,root代指xml文件的根节点
    1 from xml.etree import ElementTree as E
    2 tree = E.parse("1.xml")# 直接解析1.xml文件
    3 root = tree.getroot()# 获取xml文件的根节点

    遍历xml文件的所有内容

     1 from xml.etree import ElementTree as E
     2 
     3 #第一种解析 
     4 """
     5 str_xml = open('1.xml', 'r').read()#打开文件读取1.xml文件
     6 root = ET.XML(str_xml)#将字符串解析成xml特殊对象,root代指xml的根节点。
     7 """
     8 # 第二种解析 
     9 # 直接解析xml文件
    10 tree = E.parse("1.xml")
    11 root = tree.getroot()#获取xml文件的根节点
    12 # operation
    13 print(root.tag)#最外层标签
    14 
    15 for child in root:# 遍历1.xml的第二层
    16     print(child.tag, child.attrib) # 第二层节点的标签名称和标签属性
    17     for i in child:# 遍历XML文档的第三层
    18         print(i.tag,i.text)# 第二层节点的标签名称和内容

     因为修改的节点内容是修改在内存中的内容,需要把内存中内容写入文件中。

     1 from xml.etree import ElementTree as E
     2 
     3 # 直接解析xml文件
     4 tree = E.parse("1.xml")
     5 
     6 # 获取xml文件的根节点
     7 root = tree.getroot()
     8 
     9 #operation
    10 
    11 # 顶层标签
    12 print(root.tag)
    13 for i in root.iter('year'):# 循环year节点
    14     
    15     new_year = int(i.text) + 1# 将year节点中的内容自增一
    16     i.text = str(new_year)
    17 
    18    
    19     i.set('name', 'alex') # 设置属性
    20     i.set('age', '18')
    21     del i.attrib['name']# 删除属性
    22 
    23 
    24 #保存到文件中
    25 tree.write("3.xml", encoding='utf-8') 

    删除节点操作:

     1 from xml.etree import ElementTree as E
     2 
     3 # 解析文件方式 
     4 
     5 # 直接解析xml文件
     6 tree = E.parse("1.xml")
     7 
     8 root = tree.getroot()# 获取xml文件的根节点
     9 
    10 #operation
    11 
    12 
    13 print(root.tag)#输出顶层标签
    14 for country in root.findall('country'):# 遍历data下的所有country节点
    15     rank = int(country.find('rank').text)# 获取每一个country节点下rank节点的内容
    16     if rank > 50:
    17         
    18         root.remove(country)# 删除指定country节点
    19 tree.write("2.xml", encoding='utf-8')# 保存文件 
  • 相关阅读:
    分享一个利用HTML5制作的海浪效果代码
    3人从小公寓创业,到世界最大引擎公司,Unity创始人谈14年...
    决策树--从原理到实现
    使用行为树(Behavior Tree)实现游戏AI
    FSM(状态机)、HFSM(分层状态机)、BT(行为树)的区别
    相遇3000亿美金之巅,阿里腾讯战力与血值几何?
    深入浅出聊Unity3D项目优化:从Draw Calls到GC
    Unity性能优化专题---腾讯牛人分享经验
    高通创始人复盘30年发展历程
    Gym
  • 原文地址:https://www.cnblogs.com/evilliu/p/5601271.html
Copyright © 2020-2023  润新知