面向对象编程

1.编程范式

  我们写代码的目的是什么?就是为了能够让计算机识别我们所写的代码并完成我们的需求,规范点说,就是通过编程,用特定的语法+数据结构+特殊算法来让计算机执行特定的功能,实现一个功能的方式有很多种,对这些不同编程方式的特点进行归纳总结出来的编程方式类别,就叫做编程范式。最重要的两个编程范式就是面向过程编程和面向对象编程。发展到现在,编程已经从简单控制流中按步的指令集转变为依靠代码块完成既定的功能。


2.面向过程编程(Procedural Programming)

  面向过程是一种以过程为中心的编程思想,先分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个一次调用就可以了,以孩子上学这件事用面向过程的编程思想说明的话,可以粗略的将该过程模拟为:

  • 1.起床
  • 2.穿衣服
  • 3.洗漱吃饭
  • 4.出门上学

  这四步就是一步一步的完成的,它的顺序很重要,只需要一步一步去实现就好了,这就是面向过程编程思想

  通过下面一个例子使用面向对象的编程方法实现数据库备份的功能,首先需要将这一事件分解为三个过程:连接数据库-备份数据-测试,代码如下:

def db_con():
print("连接数据库")
def db_backup():
print("进行数据备份")
def db_backup_test():
print("备份数据可用性测试") def main():
db_con()
db_backup()
db_backup_test()
if __name__ == "__main__":
main()

  这就是面向过程的编程方式,缺点显而易见的,如果要对该程序进行修改,那么对所修改部分有所依赖的其他部分也需要进行修改,程序越大越复杂,这种编程方式的维护难度就会越来越高,所以,如果要处理的任务是复杂的,需要不断的迭代和维护,选择面向对象的编程方式是更合适的。

3.面向对象编程(Object Oriented Programming)

  面向对象编程思想更像是一个真实的世界,通过创建类和对象来描述这个世界,对函数进行封装和分类,让开发变得更快,Python从设计之初就是一门面向对象的编程语言,正因为如此,在Python中创建一个类和对象是很容易,面向对象编程其实就是对类和对象的使用。一句话:玩好面向对象,就是玩好类和对象。为了让大家能更好的理解,我通过一个小案例来引出类和对象。

  首先有这样一个需求:有很多只小狗,需要打印出哪只小狗正在跳,通过函数的方法,我可以这样实现:

dog_1={                 定义第一个小狗的属性,包含小狗的姓名和年龄
"name":"AA",
"age":2,
}
dog_2={ 定义第二个小狗的属性,包含小狗的姓名和年龄
"name":"BB",
"age":3,
} def cry(*args):
print("一个名叫%s的%s岁小狗正在“汪汪~”的叫"%(dog_1["name"],dog_1["age"])) cry(dog_1["name"],dog_1["age"]) 调用cry()函数

  这样写,有如下几个缺点:

  第一:如果需要打印无数多个小狗正在叫的信息,要从dog_1定义到dog_n,这样既会拉低效率,又会出现大量的重复代码。

  第二:如果修改了调用的小狗(如我不传入dog_1的属性,改为传入dog_2),那么在函数cry()中也要进行相应的修改。那显然是不行的。

  第三:人是不具备“汪汪”叫这个动作的,我如果定义一个人的信息,按照上述的代码写法,也是可以调用cry()函数的,那我们怎么实现将cry()函数只提供给dog这一类使用呢?带着这三个疑问,通过改为如下的代码来解决上述的三个问题:

def dog(name,age):			首先定义一个狗的函数,传入两个参数,即小狗的姓名和年龄
def cry(dog): 在dog()函数内定义嵌套函数cry,该函数只能在函数dog()内被调用
print("一个名叫%s的%s岁小狗正在“汪汪~”的叫"%(dog["name"],dog["age"]))
def init(name,age): 定义一个初始化函数
dog_1={
"name":name,
"age":age,
"cry":cry,
}
return dog_1
return init(name,age)
d_1=dog("AA",23) 该方式实质上是通过调用init函数,生成一个具有年龄,名字的小狗d_1
print(d_1)
d_1["cry"](d_1) 调用cry函数

  代码通过这种改变,cry()就只能被狗这一类调用,在外面定义一个人的属性去调用cry()函数,很明显是无法调用的。

  接下来我就引出类的概念。什么是类呢?为什么要使用类*

3.1 定义类

  类,既类别,种类,是面向对象设计中最重要的概念,类是一种数据结构,可以用它来定义对象,把数据值和行为特性融合在一起,在上面的例子中,小狗的属性“姓名”、“年龄”是所有小狗都具有的属性,这就是数据值,特定行为就是cry(),只有狗 这一类的叫声才是“汪汪”,其它的都不具备该行为特性。定义类与定义函数很类似,定义函数使用关键字def,定义类需要用到关键字class

  在python中,类的声明就是通过关键字class,后面紧跟一个类名如下:

def dog():    函数
pass 函数体代码
class dog: 类
pass 类体代码,通常由各种各样的定义和声明组成

  经典类与新式类的区别,经典类 class dog:;新式类 class dog(object),所以如果大家见到定义类后面有括号的,一定要认得。

3.2 类对象

  类对象支持两种操作:属性引用和实例化

  属性引用:当创建类对象的时候,所有在类命名空间中的名称也都是有效的属性名,对最开始说到的那个例子,我用类来实现,代码如下:

class Dog(object): 定义一个类Dog
"这是一个小狗的类"
def __init__(self,name,age): 使用__init__函数进行初始化
self.name=name
self.age=age
def cry(self):
print("一个名叫%s的%s岁小狗正在“汪汪~”的叫"%(self.name,self.age))
d_1=Dog("AA",2) 类的实例化 -->d_1
d_1.cry() 使用创建的实例,调用类方法

  属性引用与python标准语法中所有属性引用一样的语法:obj.name,在上面的例子中,Dog.nameDog.ageDog.cry等都是有效的属性引用,分别反馈整数和一个函数的对象。类的实例化使用函数(调用)表示法,将类对象看作是一个新的类实例的无参函数,如d_1=Dog("AA",2) ,该实例化就可以理解为:我定义了一条小狗d_1,它的名字是AA,它的年龄是2岁,这就相当于d_1={"name":AA,"age":2},这样定义出来的实例,就可以调用类的特定行为函数方法。当一个类定义了__init__()方法时,类实例化会为新创建的类实例自动调用__init__()发法,会将定义时传入的参数传递给该方法。

  类相关知识

  还是上面那个简单的例子:

d_1=Dog("AA",2)    #创建一个实例
print(Dog.color) #调用类的局部变量,类的作用于问题,我会在稍后进行详细解答
Dog.cry(d_1) #通过类名.函数名的方式,传入一个实例

  self是代表类的实例,在定义类的时候是必须有的,但是在调用的时候不必传入相应的参数,类的方法与普通的函数只有一个特殊的区别--它们必须有一个额外的第一个参数名称self,self返回的是当前对象的内存地址。

  python为类内置的特殊属性

print(dir(Dog))   #返回对象的一个字符串列表的目录
print(Dog.__name__) #返回一个类的名字
print(Dog.__bases__) #类的第一个父类(在后面叫讲继承的时候会将)
print(Dog.__doc__) #返回类的字符串文档
print(Dog.__bases__) #类所有父类构成的元祖(同样,在继承的时候会将)
print(Dog.__dict__) #返回一个类的字典属性
print(Dog.__module__) #返回类定义所在的模块
print(d_1.__class__) #返回一个实例对应的类

  类属性的增删改查

print(Dog.color)   #查看
Dog.color = "red" #修改
print(Dog.color)
Dog.hand=4 #增加
print(Dog.hand)
del Dog.hand #删除
print(Dog.hand)

  类,其实总体就包含了两个大的“模块”,1.数据属性;2.函数属性

  对象相关知识

  还是这样的一个例子:

class Dog(object):
"这是一个小狗的类"
def __init__(self,name,age):
self.name=name
self.age=age
def cry(self):
print("一个名叫%s的%s岁小狗正在“汪汪~”的叫"%(self.name,self.age))
d_1=Dog("AA",2)    #实例化,实质就是在运行__init__(self,name,age)函数
d_1.cry() #创建的实例调用类中的方法,self的功能其实就是将实例自动传入,所以我们看到,在类中定义cry函数的时候加
#了参数self,但在调用该函数的时候不需要再次传入d_1
print(d_1.name) #调用类中的变量
Dog.cry(d_1) #将实例传入类的方法中

  实例属性的增删改查

d_1=Dog("aa",2)
print(d_1.name) #查看
d_1.age = 6
print(d_1.age) #修改
d_1.type = "藏獒" #增加
print(d_1.type)
del d_1.type #删除
print(d_1.type)

  类和对象的基础用法我先讲解在这里,后面的文章中会持续更新后面的知识点,喜欢我博客的朋友可以随时关注的动态。

Python面向对象篇(1)-类和对象的更多相关文章

  1. Python面向对象1:类与对象

    Python的面向对象- 面向对象编程 - 基础 - 公有私有 - 继承 - 组合,Mixin- 魔法函数 - 魔法函数概述 - 构造类魔法函数 - 运算类魔法函数 # 1. 面向对象概述(Objec ...

  2. 『无为则无心』Python面向对象 — 46、类和对象

    目录 1.理解类和对象 2.类 3.对象 4.Python中的对象 5.类和对象的定义 (1)定义类 (2)创建对象 (3)练习 6.拓展:isinstance() 函数 1.理解类和对象 (1)类和 ...

  3. Python面向对象中的类和对象

    类和对象 目标 类和对象的概念 类和对象的关系 类的设计 01. 类和对象的概念 类 和 对象 是 面向对象编程的 两个 核心概念 1.1 类 类 是对一群具有 相同 特征 或者 行为 的事物的一个统 ...

  4. Python面向对象2:类与对象的成员分析及self

    # 3. 类和对象的成员分析- 类和对象都可以存储成员,成员可以归类所有,也可以归对象所有- 类存储成员时使用的是与类关联的一个对象- 独享存储成员是是存储在当前对象中- 对象访问一个成员时,如果对象 ...

  5. Python面向对象06 /元类type、反射、函数与类的区别、特殊的双下方法

    Python面向对象06 /元类type.反射.函数与类的区别.特殊的双下方法 目录 Python面向对象06 /元类type.反射.函数与类的区别.特殊的双下方法 1. 元类type 2. 反射 3 ...

  6. Python面向对象之接口类(抽象类)

    Python面向对象之接口类(抽象类):就是制定一个规范. 比如定义了一个接口类(抽象类)(他们是不可以进行实例化的,这就是他为什么是制定一个规范的原因). 他的定义是需要abc模块,要变的就是他的方 ...

  7. 第三章:Python高级编程-深入类和对象

    第三章:Python高级编程-深入类和对象 Python3高级核心技术97讲 笔记 3.1 鸭子类型和多态 """ 当看到一直鸟走起来像鸭子.游泳起来像鸭子.叫起来像鸭子 ...

  8. 086 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 03 面向对象基础总结 01 面向对象基础(类和对象)总结

    086 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 03 面向对象基础总结 01 面向对象基础(类和对象)总结 本文知识点:面向对象基础(类和对象)总结 说明 ...

  9. Python面向对象篇之元类,附Django Model核心原理

    关于元类,我写过一篇,如果你只是了解元类,看下面这一篇就足够了. Python面向对象之类的方法和属性 本篇是深度解剖,如果你觉得元类用不到,呵呵,那是因为你不了解Django. 在Python中有一 ...

随机推荐

  1. C++、Objective-C 混合编程

    在XCODE中想使用C++代码,你须要把文件的扩展名从.m改成.mm.这样才会启动g++编译器. 我们来看个測试代码: [java] view plaincopy class TestC { priv ...

  2. 高版本号chrome安装flashplayer debuger后无法使用的问题

    起因应该是苹果公司指出flash player的安全问题,还有各种原因导致google将在未来取消NPAPI的支持,所以fp们就悲剧了在高版本号chrome(42以上)默认是关闭外部安装的插件使用的, ...

  3. WARNING: Re-reading the partition table failed with error 16: Device or resource busy.

    在 mkfs.ext4 /dev/sda2 格式化硬盘空间时,可能出现这种错误. had this situation at office where I was told to re-partiti ...

  4. LINUX6安装Oracle10g无法启动安装界面解决

    ***********************************************声明*************************************************** ...

  5. JAVA入门[16]-form表单,上传文件

    一.如何传递参数 使用 @RequestParam 可以传递查询参数.例如:http://localhost:8092/category/detail?id=1 @RequestMapping(&qu ...

  6. 快看Sample代码,速学Swift语言(1)-语法速览

    Swift是苹果推出的一个比较新的语言,它除了借鉴语言如C#.Java等内容外,好像还采用了很多JavaScript脚本里面的一些脚本语法,用起来感觉非常棒,作为一个使用C#多年的技术控,对这种比较超 ...

  7. gulp提高微信小程序开发效率

      最近公司要求把一套公众号项目的页面迁移到小程序,也就意味着要重新敲一份代码,不能更繁琐了,为了节省时间,提高迁移效率,就决定自己动手用gulp搭一个简易的小程序框架,再记录一下搭建过程.希望有大神 ...

  8. (转)JVM工作原理和流程

    作为一名Java使用者,掌握JVM的体系结构也是必须的. 说起Java,人们首先想到的是Java编程语言,然而事实上,Java是一种技术,它由四方面组成:Java编程语言.Java类文件格式.Java ...

  9. 自学Zabbix3.8.1.1-可视化Visualisation-Graphs简单图表

    自学Zabbix3.8.1.1-可视化Visualisation-Graphs简单图表 Zabbix提供了一些简单的图表,用于可视化由项目收集的数据. 用户不需要进行配置工作来查看简单的图表.他们是由 ...

  10. scrapy里的selector,不能有正则提取

    参考:http://blog.csdn.net/dawnranger/article/details/50037703 Selector 有一个 .re() 方法,用来通过正则表达式来提取数据. 不同 ...