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')# 保存文件 

 

posted @ 2016-06-20 17:41  evil_liu  阅读(335)  评论(0)    收藏  举报