当前位置: 首页 > news >正文

「Python 基础」面向对象编程

文章目录

    • 1. 面向对象编程
      • 类和实例
      • 访问限制
      • 继承和多态
      • type()
      • isinstance()
      • dir()
      • 实例属性和类属性
    • 2. 面向对象高级编程
      • \_\_slots\_\_
      • @property
      • 多重继承
      • 定制类
      • 枚举类
      • 元类

1. 面向对象编程

Object Oriented Programming

简称 OOP,一种程序设计思想,以对象为程序基本单元,一个对象包含数据和数据的操作方法;

面向对象的设计思想来自自然界的类(Class)和实例(Instance),抽象出 Class,根据 Class 创建 Instance,抽象程度比函数高(既包含数据,又包含操作数据的函数);

数据封装、继承、多态是面向对象的三大特点;

类和实例

Class 是抽象的模板,是创建 Instance 的模板;

>>> class Student(object): # 定义类
...     pass
...
>>> s1 = Student() # 创建实例
>>> s1.name = 'Aurelius' # 实例属性绑定
>>> s1.name
'Aurelius'

Python 允许对实例绑定任何数据,即使一个类的两个实例,他们拥有的变量名称都可能不同;

创建实例时强制绑定属性;

class Student(object):def __init__(self, name, score):self.name = nameself.score = score

和普通函数相比,类中定义的函数第一个参数永远是实例变量 self,且调用时不用传值,self 指向创建的实例本身

数据封装

通过实例函数访问实例的数据,不直接从外部访问这些数据;

访问限制

限制外部代码对实例内部一些属性和方法的访问,可以加强代码的健壮性;

Python 没有任何强制机制限制访问权限;

在 Class 定义的内部属性前加 __ 可以把属性变成私有,通过 get_p(), set_p() 方法来访问这些属性;

__property 被 Python 解释器自动改为 _ClassName__property

__xxx__ 在 Python 中属于特殊属性,不是私有的,可以被访问的;

继承和多态

  • 继承,可以把父类的所有功能直接拿来,子类只需要新增自己特有的方法,重写覆盖父类中不适合的方法;

  • 多态,是把一个子类对象赋给一个父类变量,调用方法是子类实现;

开闭原则

对扩展开放,对修改封闭;

鸭子模式

def twice_run(animal):animal.run()animal.run()class Timer(object):def run(self):print('Start ...')

传入 twice_run() 的对象不必是 Animal 的子类,只要有 run() 即可;

因此相对静态语言,动态语言(Python)的继承不是那么必要;

type()

获取对象类型;

类型类型常量对象
intint123
strstr‘123’
函数types.FunctionTypedef fn(): pass
内建函数types.BuiltinFunctionTypeabs
匿名函数types.LambdaTypelambda x: x
生成器types.GeneratorType(x for x in range(10))

isinstance()

判断是否指定类型或指定类型元组中的一个;

>>> isinstance(x, t) # x 是对象,t 是类型,t 可以是多个类型组成的一个 tuple 对象

dir()

获取对象的所有属性和方法;

len()

实际是调用了对象的 __len__() 方法,因此按照鸭子类型,自己的类只要实现了 __len__(),也可以使用 len(myObj);

getattr(obj, pname)

获取对象的指定属性或方法,也可以传第 3 个参数作为默认值;

setattr(obj, pname, pvalue)

设置对象指定属性的值;

hasattr(obj, pname)

判断对象是否存在指定名称的属性或方法;

可以确定存在而直接访问的属性或方法,就不要使用getattr,因此可以通过hasattr判断属性或方法是否存在;

实例属性和类属性

通过实例变量或self变量绑定实例属性

通过类本身绑定的是类属性,类属性归类所有,但类的所有实例都可以访问到;

>>> class Student(object):
...     name = 'Student'
...
>>> s = Student()
>>> print(s.name)
Student
>>> print(Student.name)
Student
>>> s.name = 'Aurelius'
>>> print(s.name)
Aurelius
>>> print(Student.name)
Student
>>> del s.name
>>> print(s.name)
Student

相同名称的实例属性将屏蔽类属性(当查找到对应名称的实例属性时,即使存在同名类属性,也不会被查找到),当删除实例属性后,可以再次访问到类属性;

2. 面向对象高级编程

__slots__

动态绑定方法

Instance绑定方法,只对当前Instance有效;

class Student(object):passs = Student()def set_age(self, age):self.age = agefrom types import MethodType
s.set_age = MethodType(set_age, s)
s.set_age(25)

Class绑定方法,对所有Instance有效;

def set_score(self, score):self.score = scoreStudent.set_score = set_score
s.set_score(100)

使用 __slots__

用来限制 class 实例可以添加的属性,包括Class定义中绑定的属性;

class Student(object):# tuple定义允许绑定的属性名称__slots__ = ('name', 'age')

__slots__只对当前类有效,对子类无效;若子类也定义了__slots__,有效范围是自身加父类的范围;

不定义__slots__的类相当于其有效范围是任意属性;

@property

把一个getter方法变成属性,同时创建另一个装饰器@pname.setter,负责把另一个setter方法变成属性赋值;

class Student(object):@propertydef birth(self):return self._birth@birth.setterdef birth(self, value):self._birth = value# 只读属性@propertydef age(self):return 2020 - self._birth

多重继承

Python 允许使用多重继承,一个子类可以同时继承多个父类的所有功能;

MixIn

除了继承自主线,还额外混入其他类的功能,这种设计叫MixIn

定制类

通过一些__xxx__属性定制类;

__str__

返回给用户看到的字符串,实例的打印结果;

__repr__

返回实例调式值显示结果;

__iter__

Class实例变成一个迭代器,需要实现__next__()方法,for 循环会不断调用迭代对象的__next__()

class Fib(object):def __init__(self):self.a, self.b = 0, 1def __iter__(self):return selfdef __next__(self):self.a, self.b = self.b, self.a + self.bif self.a > 1000:raise StopIteration()return self.a

__getitem__

通过索引器或者切片读取实例的值时被调用;

class Fib(object):def __getitem__(self, n):if isinstance(n, int):a, b = 1, 1for x in range(n):a, b = b, a + breturn aif isinstance(n, slice):start, stop = n.start, n.stopif start is None:start = 0a, b = 1, 1res = []for x in range(stop):if x >= start:res.append(a)a, b = b, a + breturn res

slicestep参数和负数值可以进一步处理

__getattr__

当调用实例不存在的属性时被调用,已有的属性不会在__getattr__中查找;

__getattr__可以实现完全动态的调用

class Chain(object):def __init__(self, path=''):self._path = pathdef __getattr__(self, path):return Chain(f'{self._path}/{path}')def __call__(self, param):return Chain(f'{self._path}/{param}')def __str__(self):return self._path__repr__ = __str__print(Chain().status.user('Aurelius').timeline.list)

__call__

定义了__call__,就可以调用实例本身,__call__可以有参数;

class Student(object):def __init__(self, name):return self._namedef __call__(self, text):print(f'{self._name}: {text}')print(Student('Aurelius')('A'))

类本身的调用会执行type__call__方法

枚举类

将一组相关常量定义在一个Class中,并且不可变,成员可以直接比较;

通过Enum调用

>>> from enum import Enum
>>> Month = Enum('Month', ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'))
>>> for name, member in Month.__members__.items():
...    print(name, '=>', member, ',', member.value)
...
Jan => Month.Jan , 1
Feb => Month.Feb , 2
Mar => Month.Mar , 3
Apr => Month.Apr , 4
May => Month.May , 5
Jun => Month.Jun , 6
Jul => Month.Jul , 7
Aug => Month.Aug , 8
Sep => Month.Sep , 9
Oct => Month.Oct , 10
Nov => Month.Nov , 11
Dec => Month.Dec , 12

通过继承Enum

from enum import Enum, unique@unique
class Weekday(Enum):Sum = 0 # 默认从 1 开始,这里设置 0Mon = 1Tue = 2Wed = 3Thu = 4Fri = 5Sat = 6

获取方式

  • Enum['Name']
  • Enum.Name
  • Enum(value)

元类

type

type函数既可以返回一个对象的类型,又可以创建出新的类型;

type创建class

def fn(self, name='world'):print(f'Hello, {name}')Hello = type('Hello', (object,), dict(hello=fn))
h = Hello()
h.hello()

type() 的 3 个参数:

  • class 的名称
  • 继承的父类元组
  • class 的方法和其绑定函数的字典

metaclass

metaclass允许创建类或修改类,可以把类看作metaclass创建的实例;

定义metaclass

class ListMetaclass(type):def __new__(cls, name, bases, attrs):attrs['add'] = lambda self, value: self.append(value)return type.__new__(cls, name, bases, attrs)

__new__()的 4 个参数依次是:

  • 当前准备创建的类对象
  • 类的名称
  • 类继承的父类元组
  • 类的方法字典

定制类

# 在 Python 解释器创建 MyList 时,要通过 ListMetaclass.__new__() 来创建
class MyList(list, metaclass=ListMetaclass):pass

Python 解释器首先在当前类的定义中查找metaclass,如果没有,就继续在父类查找,知道找到,用来创建当前类,metaclass隐式继承到子类;


上一篇:「Python 基础」函数与高阶函数
专栏:《Python 基础》

PS:感谢每一位志同道合者的阅读,欢迎关注、评论、赞!

相关文章:

「Python 基础」面向对象编程

文章目录1. 面向对象编程类和实例访问限制继承和多态type()isinstance()dir()实例属性和类属性2. 面向对象高级编程\_\_slots\_\_property多重继承定制类枚举类元类1. 面向对象编程 Object Oriented Programming 简称 OOP,一种程序设计思想,以对象为程…...

【K3s】第23篇 一篇文章带你学习k3s私有镜像仓库配置

目录 1、私有镜像仓库配置 2、registries.yaml Mirrors Configs 1、私有镜像仓库配置 可以配置 Containerd 连接到私有镜像仓库,并使用它们在节点上拉取私有镜像。 启动时,K3s 会检查/etc/rancher/k3s/中是否存在registries.yaml文件,并指示 containerd 使...

Redis学习【12】之Redis 缓存

文章目录前言一 Jedis 简介二 使用 Jedis2.1 测试代码2.2 使用 JedisPool2.3 使用 JedisPooled2.4 连接 Sentinel 高可用集群2.5 连接分布式系统2.6 操作事务三 Spring Boot整合Redis3.1 创建工程3.2 定义 pom 文件3.3 完整代码3.4 总结四 高并发问题4.1 缓存穿透4.2 缓存击穿4…...

Bootargs 参数

bootargs 的参数有很多,而且随着 kernel 的发展会出现一些新的参数,使得设置会更加灵活多样1。除了我之前介绍的 root、console、earlyprintk 和 loglevel 之外,还有以下一些常用的参数:init: 用来指定内核启动后执行的第一个程序…...

Mybatis框架源码笔记(七)之Mybatis中类型转换模块(TypeHandler)解析

1、JDBC的基本操作回顾 这里使用伪代码概括一下流程: 对应数据库版本的驱动包自行下载加载驱动类 (Class.forName("com.mysql.cj.jdbc.Driver"))创建Connection连接: conn DriverManager.getConnection("jdbc:mysql://数据库IP:port/数据库名称?useUnico…...

论文阅读《Block-NeRF: Scalable Large Scene Neural View Synthesis》

论文地址:https://arxiv.org/pdf/2202.05263.pdf 复现源码:https://github.com/dvlab-research/BlockNeRFPytorch 概述 Block-NeRF是一种能够表示大规模环境的神经辐射场(Neural Radiance Fields)的变体,将 NeRF 扩展到…...

【Matlab】如何设置多个y轴

MTALAB提供了创建具有两个y轴的图,通过help yyaxis就能看到详细的使用方式。 但是如果要实现3个及以上y轴的图,就没有现成的公式使用了,如下图所示。 具体代码 % 数据准备 x10:0.01:10; y1sin(x1); x20:0.01:10; y2cos(x2); x30:0.01:10;…...

圆桌(满足客人空座需求,合理安排客人入座圆桌,准备最少的椅子)

CSDN周赛第30期第四题算法解析。 (本文获得CSDN质量评分【91】)【学习的细节是欢悦的历程】Python 官网:https://www.python.org/ Free:大咖免费“圣经”教程《 python 完全自学教程》,不仅仅是基础那么简单…… 地址:https://lq…...

如何入门大数据?

我们首先了解一下大数据到底是什么~ 大数据开发做什么? 大数据开发分两类,编写Hadoop、Spark的应用程序和对大数据处理系统本身进行开发。 大数据开发工程师主要负责公司大数据平台的开发和维护、相关工具平台的架构设计与产品开发、网络日志大数据分…...

如何在Vite项目中使用Lint保证代码质量

通常,大型前端项目都是多人参与的,由于开发者的编码习惯和喜好都不尽相同,为了降低维护成本,提高代码质量,所以需要专门的工具来进行约束,并且可以配合一些自动化工具进行检查,这种专门的工具称为Lint,可能大家接触得最多就是ESLint。 对于实现自动化代码规范检查及修…...

Spark高手之路1—Spark简介

文章目录Spark 概述1. Spark 是什么2. Spark与Hadoop比较2.1 从时间节点上来看2.2 从功能上来看3. Spark Or Hadoop4. Spark4.1 速度快4.2 易用4.3 通用4.4 兼容5. Spark 核心模块5.1 Spark-Core 和 弹性分布式数据集(RDDs)5.2 Spark SQL5.3 Spark Streaming5.4 Spark MLlib5.5…...

社科院与杜兰大学金融管理硕士项目——人生没有太晚的开始,不要过早的放弃

经常听到有人问,“我都快40了,现在学车晚不晚呢”“现在考研晚不晚?”“学画画晚不晚?”提出这些疑问的人,往往存在拖延,想法只停留在想的阶段,从来不去行动。当看到周边行动起来的人开始享受成…...

Spatial-Temporal Graph ODE Networks for Traffic Flow Forecasting

Spatial-Temporal Graph ODE Networks for Traffic Flow Forecasting 摘要 交通流量的复杂性和长范围时空相关性是难点 经典现存的工作: 1.利用浅图神经网络(shallow graph convolution networks)和 时间提取模块去分别建模空间和时间依赖…...

IP协议+以太网协议

在计算机网络体系结构的五层协议中,第三层就是负责建立网络连接,同时为上层提供服务的一层,网络层协议主要负责两件事:即地址管理和路由选择,下面就网络层的重点协议做简单介绍~~ IP协议 网际协议IP是TCP/IP体系中两…...

可视化组件届的仙女‖蝴蝶结图、玫瑰环图、小提琴图

在上一篇内容中为大家介绍了几个堪称可视化组件届吴彦祖的高级可视化图表。既然帅哥有了,怎么能少得了美女呢?今天就为大家介绍几个可视化组件届的“美女姐姐”,说一句是组件届的刘亦菲不为过。蝴蝶结图蝴蝶结图因其形似蝴蝶结而得名&#xf…...

人的高级认知:位置感

你知道吗?人有个高级认知:位置感 位置感是啥?咋提高位置感? 趣讲大白话:知道自己几斤几两 【趣讲信息科技99期】 ******************************* 位置感 就是对自己所处环境和自身存在的领悟 属于人生智慧 来源于阅历…...

MATLAB——信号的采样与恢复

**题目:**已知一个连续时间信号 其中:f01HZ,取最高有限带宽频率fm5f0。分别显示原连续时间信号波形和 3种情况下抽样信号的波形。并画出它们的幅频特性曲线,并对采样后的信号进行恢复。 step1.绘制出采样信号 这部分相对简单…...

Docker Nginx 反向代理

最近在系统性梳理网关的知识,其中网关的的功能有一个是代理,正好咱们常用的Nginx也具备次功能,今天正好使用Nginx实现一下反向代理,与后面网关的代理做一个对比,因为我使用的docker安装的Nginx,与直接部署N…...

手把手教你实现书上的队列,进来试试?

一.队列的基本概念队列的定义队列(queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。队列是一种先进先出(First In First Out)的线性表,简称FIFO。允许插入的一端称为队尾,允…...

【springboot】springboot介绍

学习资料 SpringBoot 语雀 (yuque.com)【尚硅谷】SpringBoot2零基础入门教程(spring boot2干货满满)_哔哩哔哩_bilibiliSpringBoot2核心技术与响应式编程: SpringBoot2核心技术与响应式编程 (gitee.com) Spring 和Springboot 1、Spring能做什么 1.1…...

基于算法竞赛的c++编程(28)结构体的进阶应用

结构体的嵌套与复杂数据组织 在C中,结构体可以嵌套使用,形成更复杂的数据结构。例如,可以通过嵌套结构体描述多层级数据关系: struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...

深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录

ASP.NET Core 是一个跨平台的开源框架,用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录,以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...

地震勘探——干扰波识别、井中地震时距曲线特点

目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波:可以用来解决所提出的地质任务的波;干扰波:所有妨碍辨认、追踪有效波的其他波。 地震勘探中,有效波和干扰波是相对的。例如,在反射波…...

设计模式和设计原则回顾

设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...

抖音增长新引擎:品融电商,一站式全案代运营领跑者

抖音增长新引擎:品融电商,一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中,品牌如何破浪前行?自建团队成本高、效果难控;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...

Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级

在互联网的快速发展中,高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司,近期做出了一个重大技术决策:弃用长期使用的 Nginx,转而采用其内部开发…...

Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)

目录 一、👋🏻前言 二、😈sinx波动的基本原理 三、😈波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、🌊波动优化…...

Java + Spring Boot + Mybatis 实现批量插入

在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法&#xff1a;使用 MyBatis 的 <foreach> 标签和批处理模式&#xff08;ExecutorType.BATCH&#xff09;。 方法一&#xff1a;使用 XML 的 <foreach> 标签&#xff…...

【VLNs篇】07:NavRL—在动态环境中学习安全飞行

项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战&#xff0c;克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...

免费PDF转图片工具

免费PDF转图片工具 一款简单易用的PDF转图片工具&#xff0c;可以将PDF文件快速转换为高质量PNG图片。无需安装复杂的软件&#xff0c;也不需要在线上传文件&#xff0c;保护您的隐私。 工具截图 主要特点 &#x1f680; 快速转换&#xff1a;本地转换&#xff0c;无需等待上…...