面向对象编程

  “对象并不神秘,神秘的是你的眼睛。”

                           -------Elizabeth Bowen

  “选取一个对象,对他进行修改,然后再进行一些其他的修改。”

                              -------Jasper Johns

概述

在面向对象之前,先看一下面向过程编程和函数式编程

面向过程编程

面向过程编程最容易被初学者接受,它往往使用一段长代码来实现指定功能,开发过程中最常见的就是复制粘贴。

 1 # !/usr/bin/env python3
 2 # hexm@2016/10/21
 3 
 4 import getpass
 5 
 6 '''
 7  输入用户名,如果用户名不在myInfo字典里,提示用户重新输入。
 8  然后输入密码,连续输错三次密码,退出,并加入黑名单./pass.txt
 9  当用户再次登录,提示账号被锁定。
10 '''
11 myInfo = {"hexm": "xiaoming235", "alex": "alex3714"}
12 print("现有用户如下,输入用户名请输入以下用户:")
13 for name, pas in myInfo.items():
14     print('	',name,pas)
15 count = 0
16 # 被限制用户的列表
17 limitUser = []
18 while True:
19     if count < 3:
20         # 捕获异常,第一次验证登录,pass.txt不存在
21         try:
22             limitUser = [x.strip('
') for x in open('./pass.txt', 'r')]
23         except (FileNotFoundError):
24             pass
25         # 只第一次输入用户名
26         if count == 0:
27             username = input("Please input your username:")
28 
29         # 如果用户名不存在,提示用户一直输用户名
30         while True:
31             if username not in myInfo.keys():
32                 print("no this user, reinput")
33                 username = input("Please reinput your username:")
34             else:
35                 break
36         # 如果是黑名单用户,break
37         if username in limitUser:
38             print("you account is locaked!!! Please contact xiaoming.unix@gmail.com")
39             break
40         if count == 0:
41             passwd = getpass.getpass("Please input your password:")
42         else:
43             passwd = getpass.getpass("Please reinput your password:")
44 
45         # 验证
46         if username in myInfo.keys() and passwd == myInfo[username]:
47             print("验证通过,欢迎进入CMDB,经历一系列特殊服务,现在退出!")
48             break
49         else:
50             # 第三次输入,加入黑名单
51             if count == 2:
52                 with open('./pass.txt', 'a') as f:
53                     f.write(username)
54                     f.write('
')
55                     print("password is wrong,locked your account.")
56     else:
57         break
58     count += 1
查看示例代码

函数式编程

面向过程编程从上往下垒代码,但重用性太差,函数式编程可以增加代码重用性以及可读性。

 1 #!/usr/bin/env python3
 2 #hexm@2016/10/21
 3 
 4 
 5 info = {
 6     "上海":{
 7         "浦东新区": {
 8             "张江": "51.com, 惠生公司,百度分部",
 9             "唐镇": "2345公司,abc公司"
10         },
11         "普陀区": "文华苑",
12         "闵行区": "刘德华"
13     },
14     "北京": {
15         "昌平": {
16             "沙河": "老男孩公司"
17         }
18     }
19 }
20 
21 def Page(info):
22     '''
23         递归实现的三级菜单
24     '''
25     m = 0 #m为选择的数字, 菜单有多少项选择,m会自增多少项
26     dict1 = {}
27     for x in sorted(info):
28         m = m + 1
29         print(m,x)
30         dict1[m] = x  # x为每级菜单值, 并将数字对应地区存入临时字典中, 如:{1: '上海', 2: '北京'}
31     select = input("Please select a number:")
32     if select == 'q' or select == 'quit':
33         print("正在退出...")
34         exit(0)
35     select = int(select)
36     length = [ x for x in range(1, len(info) + 1) ] #菜单所有项的和, 如length = [1, 2]
37     if select in length:  #选择的序号在length系列内
38         new = info[dict1[select]] # 下一级菜单值,如 info[dict1[1]]值为 {'普陀区': '文华苑', '浦东新区': {'唐镇': '2345公司,abc公司', '张江': '51.com, 惠生公司,百度分部'}}
39         if type(new) == dict:  #如果类型为字典,递归
40             Page(new)
41         else: #否则输出,到最后一层
42             print(new)
43     else:
44         print("输入错误,退出..")
45 Page(info)
三级菜单示例代码

面向对象编程

在面向对象之前,先了解一下什么是对象,我们都知道,python中一切皆对象,所有的数据(包括整数,浮点数,布尔值,字符串,函数)都是以对象形式存在的,无论是简单的数据海山复杂的代码模块。

所有的python对象都拥有三个特性:身份,类型和值。

  • 身份:对象的唯一标识符,通过id()得到

  • 类型:对象有不同的类型,类型决定了可以对他进行的操作,比如一个类型为int的对象支持与另一个int对象相加,同时变量的类型还决定它里面的数据是可变的(变量)还是不可变的(常量)。可通过type()查看对象的类型。

  • 值:对象表示的数据项。

面向对象编程是一种编程方式,此编程方式需要使用类和对象来实现,所以面向对象编程就是对类和对象的使用。

  举个简单例子:

  类比如说是一个生产青铜器的模具,而对象就是通过这个模具制作出来的。例如,python中的内置类string可以创建像‘cat’和‘duck’这样的字符串对象。

创建类和对象

  • class是关键字,表示类
  • 创建对象,类名称后加括号即可

 面向对象  创建对象 通过对象执行方法

 函数编程  执行函数

面向对象三大特性

一、封装

对于面向对象的封装来说,其实就是使用构造方法将内容封装到 对象 中,然后通过对象直接或者self间接获取被封装的内容。

 1 # cat foo_class.py 
 2 #!/usr/bin/env python
 3 # coding=utf-8
 4 
 5 class c1():
 6     def __init__(self, name, obj):
 7         self.name = name
 8         self.obj = obj
 9 class c2():
10     def __init__(self, name, age):
11         self.name = name
12         self.age = age
13     def show(self):
14         print(self.name)
15         return 123
16 c2obj = c2('aa', 11)
17 # 将 'aa', 11 封装到对象c2obj,self里面的name,age属性中
18 c1obj = c1('hexm', c2obj)
19 # 将'hexm',c2obj对象封装到c1obj,self里面的name, obj属性中
20 print(c1obj.obj.age)
21 
22 #c1 name = hexm
23 #c1obj.name
24 #c1obj.obj.age
25 #c1obj.obj.name
26 ret = c1obj.obj.show()
27 print(ret)
View Code

 二、继承

继承,面向对象中的继承和现实生活中的继承相同,即:子可以继承父的内容。

就是将多个类共有的方法提取到父类中,子类仅需继承父类而不必一一实现每个方法。

如果继承了多个父类呢?也就是说多继承呢?

python2和python3中是不同的,python2分为两种:

  • 深度优先
  • 广度优先   

python3只有一种:

  • 广度度优先

python2中的新式类和python3按照广度优先方式查找

python2中的经典类按照深度优先方法查找

新式类:先去A类中找,没有去B类,B类中没有,去D类,D类中没有,去C类,C类中没有,去E类,E类中没有去F类。

经典类:先去A类中找,没有去B类,B类中没有,去D类,D类中没有,去F类,F类中没有,去C类,C类中没有,去E类

 三、多态

多态简单来说就是多种类型,python函数中参数可以传任意类型的值,其他如iavac中要指定intfloat类型。

有缺点,比如阅读源码不知道是什么类型的。

什么时候使用面向对象合适

  • 当某些函数具有相同参数时,可以使用面向对象方式,将参数值一次性封装到对象,以后去对象中取值即可,如数据库的增删改查及连接数据库主机名、用户名和密码。
  • 需要创建多个事物,每个事物属性个数相同,但是值不通,如:贺晓明、朱晓静,都有姓名、年龄、血型,但都是不相同,即属性个数相同,值不同。

类和对象在内存中如何保存?

如上图所示,根据类创建对象时,对象中除了封装name和age的值外,还会保留一个类对象指针,该值指向当前对象的类,当通过obj1执行【方法一】时,过程如下:

  1. 根据当前对象中的 类对象指针 找到类中的方法
  2. 将对象obj1当做参数传给 方法的第一个参数self

 

原文地址:https://www.cnblogs.com/xiaoming279/p/6099963.html