Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >写给编程高手的Python教程(11) 深入类和对象

写给编程高手的Python教程(11) 深入类和对象

作者头像
Python之道
发布于 2020-11-12 02:40:53
发布于 2020-11-12 02:40:53
39000
代码可运行
举报
文章被收录于专栏:程序员八阿哥程序员八阿哥
运行总次数:0
代码可运行
鸭子类型和多态

当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。

例如下面三个类(Cat、Dog、Duck)的定义中都定义了say方法

class Cat: def say(self): print("I am a cat!")

class Dog: def say(self): print("I am a dog! ")

class Duck: def say(self): print("I am a duck! ")

我们就可以如下面的方法,使用这三个类的定义。

animals = [Cat, Dog, Duck] for Animal in animals: Animal().say(); 复制代码 要在Java、C++那些静态语言中,要实现上述效果,通常要使用如下的多态机制。

class Animal: def say(self): print("I am a animal!")

class Cat(Animal): def say(self): print("I am a cat!")

a_animal = Cat() a_animal.say() # 多态

扩展:列表的extend方法传递可迭代的对象即可,它会调用getitem方法

抽象基类 (abc模块)

首先看看如下定义:

class Company: def init(self, employee_list): self.employee = employee_list def len(self): return len(self.employee)

com = Company(["bobby1", "bobby2"])

抽象基类通常有以下几个优点:

判断类型 我们要判定某个类型是否是“某个鸭子”,通常有如下两种方法。

print(hasattr(com, "len")) print(isinstance(com, Company)) # 这种方式更好

扩展:abc模块collections.abc,和全局abc

强制某个子类必须实现某些方法 例如要实现了一个web框架, 集成Cache(redis、cache、、),需要设计一个抽象基类, 指定子类必须实现某些方法

from abc import abstractmethod class Cache: @abstractmethod def get(self, key): pass @abstractmethod def set(self, key, value): pass

class RedisCache(Cache): def get(self, key): pass def set(self, key, value): pass

redis = RedisCache() redis.set("key", "value")

扩展:isinstance和type的区别 首先看看如下定义:

class A: pass class B(A): #A、B可以看成是模板对象,全局只有一个 pass b = B()

print(isinstance(b, A)) #True

python中的is是判断两个对象的地址是否一样,==是判断两个对象的内容是否一样。

print(type(b) is B) #判断地址是否相同 True print(type(b) == B) #判断值是否相同 True print(type(b) is A) #False

类变量和实例变量

class A: aa = 1 def init(self, x, y): self.x = x self.y = y

a = A(2, 3) A.aa = 11 a.aa = 100 # 添加新的属性到a对象上 print(a.x, a.y, a.aa) # 100 print(A.aa) # 11

print(A.x) #抛异常

b = A(4, 6) print(b.aa)

类和实例属性的查找顺序—mro查找

多继承子类属性的查找问题,如下所述,采用广度和深度搜索都是有问题的。 父类 子类 D---->B---->A E---->C---->A

DFS: A->B->D->C->E BFS: A->B->C->D->E, 如果D和C有重名方法,C会覆盖D

菱形继承 D---->B---->A D---->C---->A

DFS: A->B->D->C, C的方法无法覆盖D的方法 BFS: A-->B->C->D

python采用一种C3的算法查找属性和函数。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class D:
  pass
class C(D):
  pass
class B(D):
  pass
class A(B, C):
  pass

print(A.mro) # 获取查询顺序

类方法、静态方法和实例方法

class Date: #构造函数 def init(self, year, month, day): self.year = year self.month = month self.day = day

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def tomorrow(self):  #实例方法
    self.day += 1

@staticmethod  # 不需要cls类型的信息
def vaild_str(date_str):
    year, month, day = tuple(date_str.split("-"))
    if int(year) > 0 and int(month) > 0 and int(month) <= 12 and int(day) > 0 and int(day) <= 31:
        return True
    else:
        return False

@staticmethod
def parse_from_string(date_str): #静态方法
    year, month, day = tuple(date_str.split("-"))
    return Date(year, month, day)

@classmethod
def parse_from(cls, date_str):  #类方法
    year, month, day = tuple(date_str.split("-"))
    return cls(year, month, day)  #cls不用硬编码了

def __str__(self):
    return "{year}/{month}/{day}".format(year=self.year, month=self.month, day=self.day)

扩展:元组是可以拆包的

date_str = "2018-12-31" year, month, day = tuple(date_str.split("-"))

数据封装和私有属性

class User: def init(self, birthday): self.__birthday = birthday

def age(self): return 2020 - self.__birthday.year

user = User(Date(1990, 2, 1))

print(user.__birthday) #报错,到达私有目的, 子类也没办法获取 print(user._User__birthday) #变形规则 print(user.age())

class Student(User): def init(self, birthday): self.__birthday = birthday

stu = Student(Date(1995, 4, 1))

print(stu._Student__birthday)

python对象的自省机制

自省是通过一定的机制查询到对象的内部结构 class Person: """ 人 """ name = "person"

class Student(Person): def init(self, school): self.school = school

stu = Student("慕课网") print(stu.dict) print(stu.name) # name属于Person类 print(Person.dict)

stu.dict["addr"] = "北京市" print(stu.addr) print(dir(stu)) # 列出对象所有属性

4-10 super真的是调用父类吗? class A: def init(self): print("A")

class B(A): def init(self): print("B") super().init()

class C(A): def init(self): print("C") super().init()

class D(B, C): def init(self): print("D") super().init() b = B() print("-------------------") d = D() #按MRO算法 super调用顺序 from threading import Thread

class MyThread(Thread): def init(self, name, user): self.user = user super().init(name=name) # MRO算法

mixin继承案例 python中的with语句 try except finally try: print("code started") raise KeyError # raise IndexError except KeyError as e: print("key error") else: print("other error") finally: print("finally...")

上下文管理器(协议)

class Sample: def enter(self): print("enter") return self

def exit(self, exc_type, exc_val, exc_tb): print("exit")

def do_something(self): print("doing something.....")

with Sample() as sample: sample.do_something()

from contextlib import contextmanager

@contextmanager def openFile(file): print("file open....") yield {} print("file close....")

print("-------------") with openFile("hao.txt"): print("file processing...")

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Python全栈开发之面向对象
类是对一群具有相同特征或者行为的事物统称,是抽象的,不能直接使用,特征被称为属性,行为被称为方法,类就是一个模板
py3study
2020/01/10
4980
第二章、深入类和对象
2.1.鸭子类型和多态 “当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。”  我们并不关心对象是什么类型,到底是不是鸭子,只关心行为。 实例一: # 鸭子类型和多态简单实例 class Dog(object): def say(self): print('a dog') class Cat(object): def say(self): print('a cat') class Duck(object):
zhang_derek
2018/05/30
9310
Python Day7
是一种新建类的方式,新建的类称为子类,子类会遗传父亲的属性,可以减少代码冗余 在python当中,子类(派生类)可以继承一个或多个父类(基类,超类)
py3study
2020/01/13
4220
python3--object类,继承与派生,super方法,钻石继承问题
{'kind': '波斯猫', 'name': '小黑', 'sex': '公'}
py3study
2018/08/02
1.2K0
[Python3]Python面向对象
最早的程序设计都是采用机器语言来编写的,直接使用二进制码来表示机器能够识别和执行的指令和数据。
py3study
2020/01/06
1.4K0
python高级编程第一讲:深入类和对象
多态的概念是应用于Java和C#这一类强类型语言中,而Python崇尚"鸭子类型"
小海怪的互联网
2019/08/23
6550
python高级编程第一讲:深入类和对象
python 继承
目录 继承 继承简介 经典类与新式类 类继承解决了什么问题 多继承的优缺点 Mixins机制 继承的查找顺序 多继实现原理 菱形结构 非菱形结构 深度优先和广度优先 深度优先: 广度优先: super()方法 抽象类 方法补充: 继承 继承简介 继承是一种创建新类的方式,新建的类可称为子类或派生类,父类可称为基类或超类 python支持多继承,新建的类可以支持一个或多个父类 '''单继承和多继承简单定义''' class Parent1: pass class Parent2: pass c
HammerZe
2022/05/09
4170
python 继承
深入理解python中的类和对象
刚开始学习python的时候或者其他的是面向对象的编程语言的时候,难免会对类和对象理解得不太清楚。所以今天和大家分享下python中的类和对象,深入理解下python中的类和对象。
sergiojune
2018/08/08
6710
深入理解python中的类和对象
Python 面向对象
# Python 面向对象 # 编程思想 编程届的两大阵营 面向过程 面向对象 区别 实物比较简单,可以用线性的思想去解决 事物比较复杂,使用简单的线性思维无法解决 共同点 面向过程和面向对象都是解决实际问题的一种思维方式 二者相辅相成,并不是对立的,解决复杂问题,通过面向对象方式便于我们从宏观上把握事物之间的复杂的关系。方便我们分析整个系统,具体到微观操作,任然使用面向过程方式来处理 # 类与对象 类 类别,分门别类,物以类聚,人类,鸟类,动物类,植物类... 类是多个类似事物组成的群体的
用户9615083
2022/12/25
3500
Python 面向对象
python元编程
通过使用property可以将方法像属性一样获取值。使用setter对方法进行赋值操作
编程黑洞
2023/03/06
3610
组合、封装、多态
继承:一种类与类的关系,一种什么是什么的关系,子类是父类的从属关系。 组合:对象与对象的关系,一种什么有什么的关系,一个对象拥有另一个对象。 组合优点:让类与类之间解耦,可扩展性高 组合的缺点:编写复杂度高 继承优点:编写复杂度低 继承缺点:耦合度高
GH
2019/12/12
5810
python学习32(面向对象_3)
继承 面向对象的编程带来的主要好处之一是代码的重用,实现这种重用的方法之一是通过继承机制。继承完全可以理解成类之间的类型和子类型关系。即一个派生类(derived class)继承基类(bass class)字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。 例如,有这样一个设计,一个Cat类型的对象派生自Animal类,这是模拟”是一个(is-a)”关系(例如,Cat是一个Animal)。 继承基本语法: class 派生类名(基类名1 [, 基类名2....]): 'Optional cl
py3study
2020/01/06
3870
Python内建函数
是计算一个数的商和余数的时候,发现基础的内建函数还没有掌握,今天空了来补一下。以下的列子均是在Python3里面支持的。
叉叉敌
2021/12/06
5470
Python内建函数
Python基础(六)——面向对象编程
  注意一点:类中自定义的方法一定要含有 self 参数,但是在调用的时候,无需为此传递参数。
py3study
2020/01/15
3700
Python基础17-面向对象
-多年互联网运维工作经验,曾负责过大规模集群架构自动化运维管理工作。 -擅长Web集群架构与自动化运维,曾负责国内某大型金融公司运维工作。 -devops项目经理兼DBA。 -开发过一套自动化运维平台(功能如下): 1)整合了各个公有云API,自主创建云主机。 2)ELK自动化收集日志功能。 3)Saltstack自动化运维统一配置管理工具。 4)Git、Jenkins自动化代码上线及自动化测试平台。 5)堡垒机,连接Linux、Windows平台及日志审计。 6)SQL执行及审批流程。 7)慢查询日志分析web界面。
DriverZeng
2022/09/26
5200
Python基础17-面向对象
【Python篇】Python 类和对象:详细讲解(中篇)
在编程中,类和对象是面向对象编程(OOP)的核心概念。Python 是一门支持面向对象编程的语言,这意味着你可以使用类和对象来组织代码,使其更加模块化、可维护和可扩展。
半截诗
2024/10/09
2620
封装,封装的原理,Property ,setter ,deleter
1,封装 ## 什么是封装 what 对外隐藏内部的属性,以及实现细节,并给外部提供使用的接口 学习封装的目的:就是为了能够限制外界对内部数据的方法 注意 :封装有隐藏的意思,但不是单纯的隐藏 python 中属性的权限分为两种:     1,分开的     没有任何限制,谁都可以访问   2,私有的     只有当前类本身能够访问   默认为公共的 ##如何封装 how 为什么要封装:   1,提高安全性 (封装属性)           2,隔离复杂度  (封装方法)      一个类
py3study
2020/01/15
7770
Python面试题之Python面向对象编程汇总
面向对象的设计思想是从自然界中来的,因为在自然界中,类(Class)和实例(Instance)的概念是很自然的。Class是一种抽象概念,比如我们定义的Class——Student,是指学生这个概念,而实例(Instance)则是一个个具体的Student,比如,Bart Simpson和Lisa Simpson是两个具体的Student。
Jetpropelledsnake21
2019/02/15
1.8K0
【说站】python静态方法的使用注意点
以上就是python静态方法的使用注意点,希望对大家有所帮助。更多Python学习指路:python基础教程
很酷的站长
2022/11/23
3340
【说站】python静态方法的使用注意点
10 . Python之面向对象
类中的方法一般都是通过对象执行的(除去类方法,静态方法外),并且对象执行这些方法都会自动将对象空间传给方法中的第一个参数self
iginkgo18
2020/09/27
4240
10 . Python之面向对象
相关推荐
Python全栈开发之面向对象
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验