一,初识面向对象
前言:我们都知道在Python中,一切皆对象,对象贯穿了Python的整个学习,本次随笔的主要内容就是谈一谈面向对象的一些基础知识。
1:面向对象设计
学过面向对象编程的人提到面向对象首先会想到的是使用class定义一个特定的类,然后实例化对象,调用方法等等。其实面向对象我觉得是一种思维方式,不仅仅是被class禁锢的特定的实现方式。下面我就使用函数来实现面向对象设计。
1 # Author : Kelvin 2 # Date : 2019/1/11 17:39 3 def person(name, gender, age): #定义一个方法(代替class的功能) 4 def eat(person): #定义一个成员方法 5 print("名字:%s 性别:%s 年龄:%s 吃饭啦!" % (person["name"], person["gender"], person["age"])) 6 def run(person): #定义一个成员方法 7 print("名字:%s 性别:%s 年龄:%s 跑步啦!" % (person["name"], person["gender"], person["age"])) 8 def init(name, gender, age): #定义一个初始化方法 9 p = {10 "name": name,11 "gender": gender,12 "age": age,13 "eat": eat,14 "run": run15 }16 return p17 return init(name, gender, age) #返回初始化函数运行的结果18 19 20 p1 = person("kelvin", "男", 22) #实例化一个对象21 print(p1) #打印实例化出来的对象22 p1["eat"](p1) #调用成员方法23 p1["run"](p1) #调用成员方法24 """25 输出结果:26 >>>:{'name': 'kelvin', 'gender': '男', 'age': 22, 'eat': <function person.<locals>.eat at 0x0000023F8EC476A8>, 'run': <function person.<locals>.run at 0x0000023F8EC47730>}27 >>>:名字:kelvin 性别:男 年龄:22 吃饭啦!28 >>>:名字:kelvin 性别:男 年龄:22 跑步啦!29 """
根据上面代码的展示,我们可以发现,面向对象设计仅是一种思维方式,也可以用函数来实现这种方式。
2:类属性的增删改查
1 #Author : Kelvin 2 #Date : 2019/1/14 12:51 3 4 class Peple: #定义一个类 5 government="opo" #定义一个成员属性 6 def __init__(self,name,age,gender): #示例初始化函数 7 self.name=name 8 self.age=age 9 self.gender=gender10 def eat(self,food): #定义一个成员函数11 print("%s 正在吃 %s"%(self.name,food))12 13 14 #查找15 print(Peple.government) #通过 类名.成员属性 可以访问成员属性16 #>>>: opo17 18 #修改19 Peple.government="ppp!" #通过 类名.成员属性=新设定得值 可以修改成员属性值20 print(Peple.government)21 #>>>: ppp!22 23 #增加24 Peple.eye="两个眼睛" #通过 类名.新设定的成员属性=属性值 可以给该类添加新成员属性25 print(Peple.eye)26 #>>>: 两个眼睛27 28 #删除29 del Peple.eye #通过 del 类名.成员属性 可以删除该类的成员属性30 print(Peple.eye) #报错,删除成功
以上是从类的角度对类的成员属性进行增删改查,下面从类的实例化对象的角度来对对象的属性进行增删改查。
1 #Author : Kelvin 2 #Date : 2019/1/14 12:51 3 4 class Peple: 5 government="opo" 6 def __init__(self,name,age,gender): 7 self.name=name 8 self.age=age 9 self.gender=gender10 def eat(self,food):11 print("%s 正在吃 %s"%(self.name,food))12 13 14 #查找15 p=Peple("kelvin",22,"男")16 print(p.government,p.age)17 p.eat("面包")18 19 #修改20 # p.__dict__["age"]=20 #尽量不要修改底层数据字典21 # print(p.__dict__)22 23 p.age=18 #通常使用这种修改方式修改成员属性24 print(p.__dict__)25 26 def test(): #修改成员函数27 print("实例对象调用方法!")28 p.test=test29 print(p.__dict__)30 p.test()31 32 #增加33 p.hight=18034 print(p.__dict__)35 print(p.hight)36 37 #删除38 del p.gnder39 print(p) #报错。说明gender已经被删除
3:介绍两个例子,透彻了解类的成员变量的知识
1 #Author : Kelvin 2 #Date : 2019/1/14 13:33 3 4 country="China!!!" 5 class Peple: 6 country="China" 7 def __init__(self,name,age,gender): 8 self.name=name 9 self.age=age10 self.gender=gender11 print("init方法内部:",country)12 def eat(self,food):13 print("%s 正在吃 %s"%(self.name,food))14 15 if __name__=="__main__":16 print("普通方法打印country:",country)17 p=Peple("kelvin",19,"man") #实例化对象的时候调用类的init方法18 print("对象的country:",p.country)19 20 #>>>: 普通方法打印country: China!!!21 #>>>: init方法内部: China!!!22 #>>>: 对象的country: China
分析:从上面一段代码可以很容易看出来,直接打印country,结果是全局变量的country值。__init__函数打印的居然不是类内部的country值!!!调用实例化对象的country值发现p.country打印结果为类内部country值。这究竟是什么原因呢?
下面我来详细讲解一下:如果存在全局变量和类内成员属性同名情况,如果打印时候直接输出变量名,无论在类的内部还是外部打印变量始终不会打印类内部的成员变量值,如果想要输出类中同名的变量值,就要通过 类名.变量名 或者 对象名.变量名 输出!!!
是不是感觉现在已经有点蒙蒙得啦?接下来再来一波代码。。。
1 #Author : Kelvin 2 #Date : 2019/1/14 13:33 3 4 class Peple: 5 country="China" 6 li=[1,2] 7 def __init__(self,name,age,gender): 8 self.name=name 9 self.age=age10 self.gender=gender11 def eat(self,food):12 print("%s 正在吃 %s"%(self.name,food))13 14 if __name__=="__main__":15 p=Peple("kelvin",19,"man")16 print("实例化对象打印列表:",p.li)17 # p.li=[1,2,3] #此时是修改实例化对象的引用对象18 p.li.append("kelvin") #此时是修改列表的值19 print(p.__dict__)20 print("类对象打印列表:",Peple.li)
这段代码有什么含义呢?
其实就是想告诉读者,如果实例化一个对象后,通过 对象.成员属性=新值 可以修改对象的该成员属性值,但是类的属性值并没有改变,但是如果没有重新赋值而只是修改例如(p.li.append("kelvin")),则对象的该属性会被修改,类的成员属性也会被改变。
原文出处:https://www.cnblogs.com/sun-10387834/p/10268645.html
作者:孙小龙