python oop 实践_Python之路(七)——Python OOP(基础篇)

本节内容:

面向对象(OO)是思想

类和对象

属性和方法

静态属性与@Property

类方法

静态方法

抽象与抽象类

接口

继承

组合

多态

封装

一、面向对象(OO)是思想

def person(name, age, sex):

#初始化

def init(name, age, sex):

person ={}

person["name"] = name

person["age"] = age

person["sex"] = sex

person["say"] = say

person["eat"] = eat

return person

def say(person):

print("My name is :%s,i'am %s old." % (person["name"], person["age"]))

def eat(person):

print("%s is eating" % person["name"])

return init(name, age, sex)

p_lw = person("老王", 42, '男')

print(p_lw["name"])

p_lw["eat"](p_lw)

#结果输出:

# 老王

# 老王 is eating

结论:OO是一种思想,class 定义类只是更加方便地实现OO思想而不是只有定义了class才是面向对象编程,同样即使定义了class也有可能不是面向对象编程

二、类和对象

前言

面向对象是一种思想、方法论,与面向过程、函数式编程一同组成了主流的三种编程思想

面向对象涵盖:面向对象分析——OOA 、面向对象设计——OOD、面向对象编程——OOP,本节重点记录Python中的OOP方法而非OO思想

类、对象的属于都是发生在特定的场景下,即不是绝对的

类与对象

类:一组事物共有的属性和方法的集合(有时也叫属性集合:数据属性,方法属性),可理解为蓝图、模板。

对象:一个个单独的事物,也叫实例

class Person:

def __init__(self,name,age,sex):

self.name = name

self.age = age

self.sex = sex

def say(self):

print("My name is :%s,i'am %s old." %(self.name,self.age))

def eat(self):

print("%s is eating" %self.name)

#实例化一个Person 对象——老王

p_lw = Person("老王", 42, '男')

#调用

p_lw.eat() # 老王 is eating

初始化构造函数__init__

用于对象实例化且被隐式调用,有如下特性:

名称唯一:__init__

至少有一个参数self,表示实例本身且在对象实例化时自动传入对象名(地址)

没有返回值

self关键字用于指代当前处理的对象

class Student():

def __init__(self):

print("当前对象的地址是:%s"%self)

if __name__ == '__main__':

student1 = Student()

print(student1)

student2 = Student()

print(student2)

#结果为:

# 当前对象的地址是:<__main__.student object at>

# <__main__.student object at>

# 当前对象的地址是:<__main__.student object at>

# <__main__.student object at>

三、属性和方法

类的属性操作

#类属性和方法

class Chinese:

country = "中国"

def __init__(self,name,age):

self.name = name

self.age = age

def chadui(self):

print("%s 又他妈插队了!" %self.name)

#属性增删改查

print(Chinese.country) #中国

p1 = Chinese("王八蛋", 22)

print(p1.country) # 中国

print(p1.__dict__) # {'name': '王八蛋', 'age': 22}

#结论: .操作符 在本对象中__dict__查找,没有 找类

Chinese.fs = "黄种人"

print(Chinese.__dict__)# 新加 'fs': '黄种人'

print(p1.fs) #同样可以找到 黄种人

#修改

Chinese.country = "中华人民共和国"

print(Chinese.country, p1.country) # 中华人民共和国 中华人民共和国

def sleep(self):

print("%s 正在睡觉." %self.name) # 王八蛋 正在睡觉.

Chinese.sleep = sleep

p1.sleep()

#结论: Python对OOP 方面的语法不是严格控制,需要程序员自行控制

对象的属性操作

class Chinese:

country = "中国"

def __init__(self,name,age):

self.name = name

self.age = age

def chadui(self):

print("%s 有他妈插队了!" %self.name)

#实例化一个对象

lw = Chinese("老王", 42)

print(lw.__dict__) # {'name': '老王', 'age': 42}

lw.aihao = "抽烟"

print(lw.__dict__) # {'name': '老王', 'age': 42, 'aihao': '抽烟'}

print(Chinese.__dict__) #没有aihaoshuxing

def sahuang(self):

print("%s 就喜欢撒谎" %self.name)

lw.sahuang = sahuang

lw.sahuang(lw) # 老王 就喜欢撒谎

#上述对象函数与类无关业余其他对象无关,仅语法可以,没有实际意义

print(lw.__dict__)

print(Chinese.__dict__) # 没有撒谎函数

#拿了绿卡

lw.country = "美国" #赋值语句都是新建,对象不能修改类属性

print(lw.__dict__)

# {'name': '老王', 'age': 42, 'aihao': '抽烟', 'sahuang': , 'country': '美国'}

# 删除——遣回中国

del lw.country

print(lw.country) #中国

结论:对象的属性单独维护在对象中,独立于类的属性。对象查找属性时先从本对象__dict__中查找,没有在到类__dict__中查找

四、静态属性

这个专有名词歧义很大,首先类有自己的属性,这些属性相对于对象来说就是静态的属性。而这里的静态属性是指:在类的方法(仅有self参数)前加入装饰器@property

class Room:

style = "别墅" #类属性

def __init__(self, name, addr, length, width, height):

self.name = name

self.addr =addr

self.length = length

self.width = width

self.height = height

def get_height(self):

print("%s 房间的高度为: %s" % (self.name, self.height))

def ruzhu(self, owner):

print("%s 入住了 %s" % (owner, self.name))

@property

def area(self):

return self.length * self.width

# def cal_area(self):

# return self.length * self.width

room1 = Room("山村人家" ,"峦峰岗",100,50,20)

room1.ruzhu("张三") # 张三 入住了 山村人家

#求room1 的面积

# print(room1.cal_area()) # 5000

#方法二、使用@property 装饰器

print(room1.area) # 5000

print(room1.__dict__) #没有area 属性的

#从外部看来就是一个对象属性

结论(个人理解):Python 中 类其实可以没有属性,即:属性在有值的情况下才有意义。所以类中仅保存这类事物的共有方法即可。例如:一个人他虽然有国籍,名字,年龄,但是人这个类其实是没有这些的,Python 中把这类属性直接保存在每个对象属性中,那有时候需要对象的间接属性,如:取Room 占多少平米,通过@property 修饰符把一个方法转换成一个属性(至少表面上看起来是这样的)

五、类方法

类中的方法不与对象绑定(默认绑定即第一个参数为self),而与类自身进行绑定(self ->cls)。可以定制化调用__init__方法创建对象

class Dog:

def __int__(self,name,color):

self.name = name

self.color = color

def jiao(self):

print("%:汪汪汪!" %self.name)

@classmethod

def about_me(cls):

print("这个是一个Dog 类")

Dog.about_me()

六、静态方法

类中不与对象(self)也不与类(cls) 绑定的方法。一般是作为工具方法来使用。

import time

class TimeTest:

def __init__(self,hour,min,sec):

self.hour = hour

self.min = min

self.sec = sec

#静态方法,仅作用域限定在类中,其实就是一个独立的函数,可以有参数

@staticmethod

def show_currtime(var1,var2):

print(time.asctime())

TimeTest.show_currtime(1,2)

七、抽象与抽象类

抽象:现实生活中首先识别到一个个具体的对象,在对象的基础上提取共有属性。这个动作也叫泛化

OOA(面向对象分析)步骤:

识别一个个对象

提取对象特征,对象间的关系

抽象特征,组成类

循环第三步骤,形成类的层级关系图

抽象类

类的抽象,更抽象地描述事物

import abc

#抽象类,不能被实例化,只能被继承使用

class Shape_2D(metaclass=abc.ABCMeta):

type = "二维图形"

#初始化方法被抽象定义,so 不能实例化一个Shape_2D 对象

@abc.abstractmethod

def __init__(self):

'''

抽象方法

'''

pass

class Circle(Shape_2D):

type="圆"

def __init__(self,x,y,radius):

pass

class Line(Shape_2D):

type = "线"

def __init__(self,x1,y1,x2,y2):

pass

c1 = Circle(1,2,3)

print(c1.type) # 圆

八、接口

语法与抽象类相同,表示一组特定功能提供统一的对外功能

import abc

class I_Pay(metaclass=abc.ABCMeta):

#支付

@abc.abstractmethod

def pay(self):

pass

#退款

@abc.abstractmethod

def tuikuan(self):

pass

class AppleMobile(I_Pay):

def pay(self):

print("苹果手机支付")

def tuikuan(self):

print("苹果手机退款")

class XMMobile(I_Pay):

def pay(self):

print("小米手机支付")

def tuikuan(self):

print("小米手机退款")

抽象类 vs 接口

抽象类:还是一个类,仅对类进一步抽象;接口:特定功能的规范性描述

抽象类:描述什么是什么关系,例:战斗机、民用机是飞机,麻雀是鸟;接口:描述什么有什么功能的关系,例:飞机,鸟都有飞翔的功能

注意:在OO中所有概念(类,抽象类,接口等)都是在特定场景下,而非绝对

九、继承

即抽象的逆过程。 对象与类 '延续共有属性' 叫 : 实例化; 类与类 '延续共有属性 '叫继承,存在父-子关系。

MRO

一个元祖,记录继承顺序。

#继承树

# A

# B C

# D E

# F

class A:

def test(self):

print("A")

class B(A):

def test(self):

print("B")

class C(A):

def test(self):

print("C")

class D(B):

def test(self):

print("D")

pass

class E(C):

def test(self):

print("E")

class F(D,E):

def test(self):

print("F")

f = F()

f.test()

#新式类广度优先:左边 F->D->B->E->C->A

#老式深度优先: F->D->B->A->E->C

print(F.__mro__)

# (, , , ,

# , , )

super关键字

子类引用父类内容,使用super关键字

class Stuff:

def __init__(self,name,age,sex):

self.name = name

self.age = age

self.sex = sex

def say(self):

print("我的名字 %s" %self.name)

class Teacher(Stuff):

def __init__(self,name,age,sex,zc):

super().__init__(name,age,sex)

# super(Teacher, self).__init__(name,age,sex)

self.zc = zc

t1 = Teacher("老张",12,'男','副高')

t1.say() # 我的名字 老张

十、组合

类与类的关系除了继承,还有组合、聚合、关联

组合:一个类是其中一个类的组成部分,且紧密相关。例:Linux硬盘操作模块与LinuxOS内核,独立于Linux内核硬盘操作这个模块无法使用

聚合:一个类是一个类的一部分,但是可独立使用。例:发动机与汽车,发动机可以独立出来使用

关联:最常用,两个类都是独立的,但存在某种关系。例如:学校老师绩效考核系统中,学校是一个类,老师是一个类,但这里的老师与学校存在关联

十一、多态

功能函数参数采用父类类型定义,调用时根据传入不同的子类对象实际调用其子类自身的方法,从而同一函数看起来呈现不同的形态。没有继承就没有多态

#多态

class Animal:

def __init__(self):

pass

def move(self):

pass

class Dog(Animal):

def __init__(self):

pass

def move(self):

print("Dog is running")

class Bird(Animal):

def __init__(self):

pass

def move(self):

print("Bird is flying")

#函数让传输的动物移动两次

def run(animal):

animal.move()

animal.move()

if __name__ == "__main__":

dog1 = Dog()

bird1 = Bird()

run(dog1)

run(bird1)

#结果:

# Dog is running

# Dog is running

# Bird is flying

# Bird is flying

#好处: 调用程序仅判断一类事物,仅针对同一类型进行处理。例如:新增一个动物,本程序亦然运行无恙

十二、封装

目的

封装的目的就是隐藏复杂性。例如: 撒尿是经过一系列的动作,但是你本身是不清楚的(医生除外),掏出你的枪开干就完事了。

封装的最终结果做到内外有别,仅给出对方需要的数据,不少也不多。

方法

Python 对封装没有提供特有的关键字,仅通过变量名和约定来完成

_foo:保护的方法/属性 protect

__foo:私有方法/属性,只允许类的内部访问 private

foo:普通变量名,可以被外部访问  public

class Employee:

def __init__(self,name,age,race,salary):

self.name = name

self.age = age

self._race = race

self.__salary = salary

e = Employee('老王',55,'黑人',50000)

print(e._race) # 可以访问但不建议使用,提供给子类访问的

# print(e.__salary) # AttributeError: 'Employee' object has no attribute '_salary'

print(e._Employee__salary) # 一定要看也可以

#结论: Python 中很多功能都是不强制,讲究约定俗称

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
作者介绍作者Toby:持牌照消费金融模型专家,和中科院,中科大教授保持长期项目合作;和同盾,聚信立等外部数据源公司有项目对接。熟悉消费金融场景业务,线上线下业务,包括现金贷,商品贷,医美,反欺诈,汽车金融等等。模型项目200+,擅长Python机器学习建模,对于变量筛选,衍生变量构造,变量缺失率高,正负样本不平衡,共线性高,多算法比较,调参等疑难问题有良好解决方法。作者赠语--与其被人工智能代替,不如主动学习编程,设计机器为自己服务 课程背景我在多次python培训时,对学员讲解编程对人生具有重大影响。曾经大学毕业时也迷茫过,不知道以后要干嘛。面对招聘会上密密麻麻的人群,经不知所措。自从接触python编程后,我对这门快速,高效程序语言表示惊讶,从此人生轨迹悄悄发生改变。编程不是计算机专业的垄断,我多次提醒学生。在欧美日,美术专业,音乐专业,英语专业,考古专业,数学专业,物理专业的学生同样大量使用编程。编程只是一个工具,让我们快速实现大脑的逻辑算法。不要在怀疑自己了,动手吧,敲下第一行代码 “”hello world!“”,恭喜你,你已经是一名程序员了,对就这么简单,follow me!python编程让曾经迷茫的我发现了一个奇妙世界,我很乐意分享这些宝贵的资源和经验,希望帮助到同样困惑的你!为了让广大学员免费和快速学习python,我为大家准备了新的课程《Python入门经典(2K超清)_》。此课程目录如下,大概包括python环境搭建,资源介绍,基础知识和就业指导。视频采用专用显卡录制,支持2K超清分辨率,学员可以看清每一行代码和文字,具有较好用户体验。 课程概述本课程避免一来讲解python语法,而是用另一种思路讲述python。让初学者彻底明白python到底可用于什么领域,学了有什么好处。本课程既适合初学者夯实基础,又能帮助Python程序员提升技能,即使是中高级Python程序员,也能从书里找到耳目一新的内容。课程第一章介绍python官网,软件下载地址,和专用数据科学高级版本框架anaconda。初学者如何用pip安装python的第三方包。第二章推荐一些python学习书籍和免费数据库资源,用于机器学习和人工智能建模。第三章介绍python速查表,节约菜鸟和老鸟查阅语法时间;还有基础语法,展示了Python DIY 植物大战僵尸的游戏。最后提供Python就业指导,提供比公务员更好金饭碗。作者想分享所有会的Python知识给大家,但时间有限,最后分享一些学习方法给学员,让大家以不变应万变。  

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值