python学习--关注容易被忽略的知识点--(五)面向对象编程

Python中self用法详解 Python中类、实例以及self的详解 阅读详情

本系列文章回顾了 python大部分关键的知识点,关注那些容易被忽略的知识点。适用于有一定python基础的python学习者。
本系列文章主要参考廖雪峰的python学习网站。该学习网站内容全面,通俗易懂,强烈推荐初学者在这个网站学习python。

全系列:
(一)python基础
(二)函数
(三)高级特性
(四)函数式编程
(五)面向对象编程

面向对象编程

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

类和实例

面向对象最重要的概念就是类(Class)和实例(Instance),必须牢记类是抽象的模板,比如Student类,而实例是根据类创建出来的一个个具体的“对象”,每个对象都拥有相同的方法,但各自的数据可能不同。

数据封装

每个实例拥有各自的数据,通过函数访问这些数据,从而将数据封装起来。

class Student(object):
    def __init__(self, name, score):
        self.name = name
        self.score = score
        
    def print_score(self):
        print('%s: %s' % (self.name, self.score))
    
    def get_grade(self):
        if self.score >= 90:
            return 'A'
        elif self.score >= 60:
            return 'B'
        else:
            return 'C'

“封装”的另一个好处是可以增加新的方法,比如get_grade。

其他

Python允许对实例变量绑定任何数据。
对于两个实例变量,虽然它们都是同一个类的不同实例,但拥有的变量名称都可能不同。

>>> bart = Student('Bart Simpson', 59)
>>> lisa = Student('Lisa Simpson', 87)
>>> bart.age = 8
>>> bart.age
8
>>> lisa.age
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Student' object has no attribute 'age'

访问限制

从前面Student类的定义来看,外部代码还是可以自由地修改一个实例的name、score属性:

>>> bart = Student('Bart Simpson', 59)
>>> bart.score
59
>>> bart.score = 99
>>> bart.score
99

如果要让内部属性不被外部访问,可以把属性的名称前加上两个下划线__,在Python中,实例的变量名如果以__开头,就变成了一个私有变量(private),只有内部可以访问,外部不能访问。

class Student(object):

    def __init__(self, name, score):
        self.__name = name
        self.__score = score

    def print_score(self):
        print('%s: %s' % (self.__name, self.__score))

>>> bart = Student('Bart Simpson', 59)
>>> bart.__name
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Student' object has no attribute '__name'

这样就确保了外部代码不能随意修改对象内部的状态,这样通过访问限制的保护,代码更加健壮。

如果外部需要获取或修改name和score的值,可以增加get_name和get_score这样的方法。

class Student(object):
    ...
    def get_name(self):
        return self.__name

    def get_score(self):
        return self.__score
    def set_score(self, score):
        if 0 <= score <= 100:
            self.__score = score
        else:
            raise ValueError('bad score')

在set_score函数中还可以进行参数检查,加强了程序的鲁棒性。

  • Python中,变量名类似__xxx__的,也就是以双下划线开头,并且以双下划线结尾的,是特殊变量。
    特殊变量是可以直接访问的,不是private变量,所以,不能用__name__、__score__这样的变量名。
  • 还有以单下划线开头的,如_name,这样的实例变量外部是可以访问的,但是,按照约定俗成的规定,当你看到这样的变量时,意思就是,“虽然我可以被访问,但是,请把我视为私有变量,不要随意访问。
  • 双下划线开头的实例变量是不是一定不能从外部访问呢?其实也不是。不能直接访问__name是因为Python解释器对外把__name变量改成了_Student__name,所以,仍然可以通过_Student__name来访问__name变量:
>>> bart._Student__name
'Bart Simpson'

Python本身没有任何机制阻止你干坏事,一切全靠自觉。

>>> bart = Student('Bart Simpson', 59)
>>> bart.get_name()
'Bart Simpson'
>>> bart.__name = 'New Name' # 设置__name变量!
>>> bart.__name
'New Name'

表面上看,外部代码“成功”地设置了__name变量,但实际上这个__name变量和class内部的__name变量不是一个变量!内部的__name变量已经被Python解释器自动改成了_Student__name,而外部代码给bart新增了一个__name变量

>>> bart.get_name() # get_name()内部返回self.__name
'Bart Simpson'

继承和多态

  • 继承可以获得父类的全部功能。继承可以增加自己的方法,也可以重写(覆盖)父类的方法。(python中的重写和重载:https://www.cnblogs.com/Hondsome/p/5962889.html)
  • 在继承关系中,如果一个实例的数据类型是某个子类,那它的数据类型也可以被看做是父类。但是,反过来就不行。
  • 对于一个变量,我们只需要知道它是Animal类型,无需确切地知道它的子类型,就可以放心地调用run()方法,而具体调用的run()方法是作用在Animal、Dog、Cat还是Tortoise对象上,由运行时该对象的确切类型决定,这就是多态真正的威力:
    调用方只管调用,不管细节,而当我们新增一种Animal的子类时,只要确保run()方法编写正确,不用管原来的代码是如何调用的。这就是著名的“开闭”原则:
    • 对扩展开放:允许新增Animal子类;
    • 对修改封闭:不需要修改依赖Animal类型的run_twice()等函数。
class Animal(object):
    def run(self):
        print('Animal is running...')

class Dog(Animal):
    def run(self):
        print('Dog is running...')

    def eat(self):
        print('Eating meat...')

class Cat(Animal):
    def run(self):
        print('Cat is running...')
        
class Tortoise(Animal):
    def run(self):
        print('Tortoise is running slowly...')
        
def run_twice(animal):
    animal.run()
    animal.run()
    
# test
>>> run_twice(Dog())
Dog is running...
Dog is running...
>>> run_twice(Cat())
Cat is running...
Cat is running...
>>> run_twice(Tortoise())
Tortoise is running slowly...
Tortoise is running slowly...

获取对象信息

type()

判断对象类型,使用type()函数。

>>> type(123)
<class 'int'>
>>> type('str')
<class 'str'>
>>> type(None)
<type(None) 'NoneType'>

如何判断一个对象是否是函数?

>>> import types
>>> def fn():
...     pass
...
>>> type(fn)==types.FunctionType
True
>>> type(abs)==types.BuiltinFunctionType
True
>>> type(lambda x: x)==types.LambdaType
True
>>> type((x for x in range(10)))==types.GeneratorType
True

isinstance()

对于class的继承关系来说,使用type()就很不方便。我们要判断class的类型,可以使用isinstance()函数。

# 判断类和继承关系
>>> a = Animal()
>>> d = Dog()
>>> h = Husky()
>>> isinstance(h, Husky)
True
>>> isinstance(h, Dog)
True
>>> isinstance(h, Animal)
True
# 判断常见数据类型
>>> isinstance('a', str)
True
>>> isinstance(123, int)
True
>>> isinstance(b'a', bytes)
True
# 判断一个变量是否是某些类型中的一种
>>> isinstance([1, 2, 3], (list, tuple))
True
>>> isinstance((1, 2, 3), (list, tuple))
True

dir()

如果要获得一个对象的所有属性和方法,可以使用dir()函数,它返回一个包含字符串的list,比如,获得一个str对象的所有属性和方法。

>>> dir('ABC')
['__add__', '__class__',..., '__subclasshook__', 'capitalize', 'casefold',..., 'zfill']

配合getattr()、setattr()以及hasattr(),我们可以直接操作一个对象的状态:

>>> class MyObject(object):
...     def __init__(self):
...         self.x = 9
...     def power(self):
...         return self.x * self.x
...
>>> obj = MyObject()

# 操作对象的属性
>>> hasattr(obj, 'x') # 有属性'x'吗?
True
>>> obj.x
9
>>> hasattr(obj, 'y') # 有属性'y'吗?
False
>>> setattr(obj, 'y', 19) # 设置一个属性'y'
>>> hasattr(obj, 'y') # 有属性'y'吗?
True
>>> getattr(obj, 'y') # 获取属性'y'
19
>>> obj.y # 获取属性'y'
19
>>> getattr(obj, 'z', 404) # 获取属性'z',如果不存在,返回默认值404
404

# 获得对象的方法
>>> hasattr(obj, 'power') # 有属性'power'吗?
True
>>> getattr(obj, 'power') # 获取属性'power'
<bound method MyObject.power of <__main__.MyObject object at 0x10077a6a0>>
>>> fn = getattr(obj, 'power') # 获取属性'power'并赋值到变量fn
>>> fn # fn指向obj.power
<bound method MyObject.power of <__main__.MyObject object at 0x10077a6a0>>
>>> fn() # 调用fn()与调用obj.power()是一样的
81

实例属性和类属性

类属性属于类所有,所有实例共享一个属性。

# 类属性
class Student(object):
    name = 'Student'
...
>>> s = Student() # 创建实例s
>>> print(s.name) # 打印name属性,因为实例并没有name属性,所以会继续查找class的name属性
Student
>>> print(Student.name) # 打印类的name属性
Student
>>> s.name = 'Michael' # 给实例绑定name属性
>>> print(s.name) # 由于实例属性优先级比类属性高,因此,它会屏蔽掉类的name属性
Michael
>>> print(Student.name) # 但是类属性并未消失,用Student.name仍然可以访问
Student
>>> del s.name # 如果删除实例的name属性
>>> print(s.name) # 再次调用s.name,由于实例的name属性没有找到,类的name属性就显示出来了
Student

注意:
千万不要对实例属性和类属性使用相同的名字,因为相同名称的实例属性将屏蔽掉类属性

Python面向对象编程异常处理最佳实践 想象一下你正在玩一款冒险游戏,在游戏中,你可能会遇到各种突发状况,比如突然遇到怪物攻击,或者前方道路被巨石挡住。掌握异常处理的最佳实践,就如同在游戏中学会应对各种突发状况的技巧,能让你的程序更加健壮,减少崩溃的风险。通过学习异常处理,你可以让程序在遇到错误时不会直接崩溃,而是能够做出合理的处理,继续运行或者给出友好的错误提示。接下来,我们将沿着这样的学习路径:先了解异常处理的基本概念,再学习如何捕获和处理异常,接着探讨最佳实践,最后通过实际案例来巩固所学知识。语句,程序不会崩溃,而是会执行。 阅读详情

相关推荐

【Python学习】面向对象编程 Class

python随笔

跪求关注点赞收藏 2070

python:内置类属性方法

Python 的类内置了一些通用的属性和方法,方便我们进行操作和对类的管理。我们可以使用dir(ClassName)来查看这些属性和方法,其中前后双下划线的如__dir__就是内置的。

OceanStar的博客 1194

新能源场站必看:一次调频与AGC/AVC的协同控制逻辑解析(含典型拓扑图)

本文深度解析了新能源场站中一次调频与AGC/AVC的协同控制逻辑。针对电网频率与电压稳定需求,详细阐述了三者在响应时序、控制目标上的分工与配合,并重点剖析了以RCL-0923装置为核心的指令融合架构与典型拓扑,为场站实现高效、稳定的协同运行提供了清晰的实践指导。

brown的博客 1062

python学生类的使用_Python类的使用总结

Python是一个面向对象的解释型语言,所以当然也有类的概念。在Python中,所有数据类型都可以视为对象,当然也可以自定义对象,自定义的对象数据类型就是面向对象中类(Class)的概念。之前接触类的概念是在学习C++时,现在学习了Python之后,觉得两者还是有很大的区别的。面向对象的思想是一样的,但是python作为更高级的语言,在类的定义与使用更加简便。类的定义Python中,定义类是通过c...

weixin_39859715的博客 1364

Unity Spine动画控制全攻略:播放、回调与停止的实战技巧

本文深入解析Unity中Spine动画的核心控制技巧,涵盖动画播放、轨道分层、事件回调与平滑停止等实战方法。通过封装SpineAnimationController,详细讲解了如何利用动画播放结束回调实现精准的游戏逻辑同步,并提供了避免内存泄漏和动画卡顿的避坑指南,助力开发者打造流畅专业的2D游戏动画系统。

weixin_29021291的博客 381

MobilenetV1、V2、V3系列详解

Mobilenet系列模型作为当前主流的端侧轻量级模型被广泛应用,很多算法都会使用其作为backbone提取特征,这一章对Mobilenet系列模型V1,V2,V3做一个总结。

turned的博客 1万+

python学习--关注容易被忽略的知识点---(一)python基础

本系列文章回顾了 python大部分关键的知识点,关注那些容易被忽略的知识点。适用于有一定python基础的python学习者。 本系列文章主要参考廖雪峰的python学习网站。该学习网站内容全面,通俗易懂,强烈推荐初学者在这个网站学习python。 全系列: (一)python基础 文章目录前言python基础数据类型和变量字符串和编码字符编码python字符串格式化输出list和tuplelisttupledict和setdictset不可变对象 前言 python是一种高级程序设计语言。 pyth.

lingpy的博客 467

使用Dify搭建音频文件转文本工作流

使用Dify搭建音频文件转文本工作流

zyx_bx的博客 5624

Python一些常被忽略的知识点

深入了解Python,除了掌握其基础语法和常用功能外,还需要注意一些常被忽略的知识点。

2401_89383634的博客 1039

将Python爬取的数据导入钉钉多维表

摘要:本文介绍将Python爬取的数据导入钉钉多维表的完整解决方案。首先通过requests库爬取数据并解析为结构化格式,然后使用钉钉开放平台API对接多维表。关键步骤包括获取app_key、app_secret等凭证,通过OAuth2获取access_token,以及批量写入记录。文章详细说明了参数获取位置、字段类型匹配、权限配置等注意事项,并提供了错误处理建议和性能优化方法。适用于需要将网络数据同步到钉钉多维表的开发场景。

IT深耕十余载,大道之简 2131

基于STM32、HAL库的WF162A 11BA T&R气压传感器 驱动程序设计

/ 转换为7位地址。* @param temperature: 存储读取到的温度值(°C)* @param temperature: 存储读取到的温度值(°C)* @param pressure: 存储读取到的压力值(bar)* @param pressure: 存储读取到的压力值(bar)* @param range: 压力范围(bar)

corlin6688的博客 363

python学习--关注容易被忽略的知识点--(三)高级特性

高级特性 迭代 如果给定一个list或tuple,我们可以通过for循环来遍历这个list或tuple,这种遍历我们称为迭代(Iteration)。如: >>> for ch in 'ABC': ... print(ch) ... A B C 如何判断一个对象是可迭代对象呢?方法是通过collections模块的Iterable类型判断: >>> from collections import Iterable >>> isinstance('

lingpy的博客 351

手把手教你学pcie--(PCIe) 写请求的流程

通过上述流程,我们可以看到PCIe写请求的完整过程,包括请求的构建、发送、接收、处理和响应。这种请求-响应模型确保了数据传输的可靠性和有序性。

MHD0815的博客 158

python学习--关注容易被忽略的知识点--(二)函数

本系列文章回顾了 python大部分关键的知识点,关注那些容易被忽略的知识点。适用于有一定python基础的python学习者。 本系列文章主要参考廖雪峰的python学习网站。该学习网站内容全面,通俗易懂,强烈推荐初学者在这个网站学习python。 全系列 (一)python基础 (二)函数 函数 调用和定义函数 调用 Python内置了很多有用的函数,可以直接调用。 函数名其实就是指向一个函数对象的引用,完全可以把函数名赋给一个变量,相当于给这个函数起了一个“别名”: >>> a .

lingpy的博客 350

Pytorch实现EdgeCNN(基于PyTorch实现)

本专栏整理了《图神经网络代码实战》,内包含了不同图神经网络的相关代码实现(PyG以及自实现),理论与实践相结合,如GCN、GAT、GraphSAGE等经典图网络,每一个代码实例都附带有完整的代码。

优快云 精品推荐 1万+

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

【Python】进阶学习:一文了解如何忽略UserWarning的兼容性警告

🚀【Python进阶秘籍】解锁UserWarning新姿势,告别烦人警告!🔥 还在为Python中的UserWarning烦恼吗?别担心,我们为你揭秘如何高效忽略这些兼容性警告!🔍 从认识UserWarning开始,我们逐步深入,教你使用warnings模块轻松管理警告。更厉害的是,我们还将分享如何在特定上下文中精准忽略警告,让你的代码更清爽!💡 别忘了,我们还会帮你理清警告与异常的区别,让你编程更得心应手!🔍 最后,总结回顾,让你对忽略UserWarning的技巧一网打尽!🔄

创作高质量博文,分享知识,共同进步! 5119

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

python学习--关注容易被忽略的知识点--(四)函数式编程

本系列文章回顾了 python大部分关键的知识点,关注那些容易被忽略的知识点。适用于有一定python基础的python学习者。 本系列文章主要参考廖雪峰的python学习网站。该学习网站内容全面,通俗易懂,强烈推荐初学者在这个网站学习python。 全系列: (一)python基础 (二)函数 (三)高级特性 (四)函数式编程 文章目录函数式编程高阶函数map/reducefiltersorted返回函数匿名函数装饰器偏函数 函数式编程 函数是Python内建支持的一种封装,我们通过把大段代码拆成函数.

lingpy的博客 364

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

Python筑基之旅-面向对象编程(OOP)

面向对象编程(OOP)

ygb_1024的博客 1555

Python 之 可能会忽略的知识点(一)

在掌握了一门语言之后, 我们可能在使用的过程中渐渐地忽略了一些小知识点, 本文提供了一些自己觉得有必要记录一下的小知识点, 涉及到python基础编程和面向对象编程。

恋梦轩 289

python 面向对象编程

面向对象编程概念(OOP) 面向过程是编年史: 按照时间先后顺序, 一条一条的记录发生的事情. 面向对象是记传史: 按照每个王侯将相的维度, 记录这个人是谁, 有哪些特点, 做过哪些事情 所以史记其实是中国古代的一个非常成功的应用了 OOP 思想的著作 OOP是一种编程思想. 所谓 “思想”, 指的是解决一类问题时, 使用的一系列的方法手段, 一套组合拳. 我们看看这套组合拳都有哪些招式 抽象 抽象是指对现实世界问题和实体的本质表现, 行为, 特征进行建模; 抽象的反义词是 "具体“ 面向对象的本质是: 把

sakeww的博客 1458

python 忽略异常_python如何忽略异常

python一般使用try…except…处理异常。try: #可能会出现异常的代码,放在try下code1 #如果try内部任意一行代码出现异常,# 直接跳转至except,执行except下代码code2except:code3code4此方法只要有一个异常,程序就不继续执行了。当循环中出现异常时,如何跳过循环中的异常继续执行。比如当我move一个文件的时候,如果目...

weixin_30788095的博客 1053

Python的核心知识点整理大全66(已完结撒花)

就这个项目而言,恢复到前一个状态微不足道,但如果我们开发的是大型项目,其中数十个 文件都被修改了,那么恢复到前一个状态,将撤销自最后一次提交后对这些文件所做的所有修改。我们可以提交所做的修改,但这次我们不提交 所做的修改,而要恢复到最后一个提交(我们知道,那次提交时项目能够正常地运行)。检出以前的提交后,你将离开分支master,并进入Git所说的分离头指针(detached HEAD) 状态(见1)。输出指出了我们当前所在的分支(见1)、被修改了的文件的名称(见2),还指出了所做的 修改未提交(见3)。

私信up主,有惊喜 2523

Python进阶:装饰器与面向对象编程实战解析

Python作为一门动态语言,其高阶函数特性与面向对象机制是构建复杂系统的关键。装饰器基于闭包实现,通过@语法糖实现函数功能扩展,在Web框架路由、性能监控等场景广泛应用。面向对象编程中,类方法与静态方法的合理使用能提升代码组织性,而属性访问控制(@property)和MRO规则则是设计可扩展系统的核心知识。针对装饰器元信息丢失、可变默认参数等常见问题,可采用functools.wraps和None默认值等工程解决方案。掌握这些进阶特性,能够显著提升代码质量与开发效率,是Python开发者从入门到精通的必经

一个2年工作经验的程序测试员 454

学习Python,千万不要把它忽略了

今天小编和小伙伴们分享一下Python的基础的知识,字符串,虽然基础,但还是很重要的哦。 昨天有个小伙伴和我说,说是开始的时候是觉得很简单呐,一直是急着学,学了一段时间了,又返回来补基础了,基础不扎实,考试的时候都不会。所以我觉得大家不要觉得 Python 简单就急着上赶着学,快是没有用的,重要的在于对细节的把握。简单并不代表你就可以不上心了,希望朋友们用心学了。 在这里我还是小编推荐一个学python的学习老师围鑫(同音),前排的是:762,中间一排是:459,后排的一组是:510 ,把以上三组字母按照

zihong523的博客 166

经常被大家忽略的,几个Python技巧,太实用了_python常被用到哪些

🍅 硬核资料:关注即可领取PPT模板、简历模板、行业经典书籍PDF。🍅 技术互助:技术群大佬指点迷津,你的问题可能不是问题,求资源在群里喊一声。🍅 面试题库:由技术群里的小伙伴们共同投稿,热乎的大厂面试真题,持续更新中。🍅 知识体系:含编程语言、算法、大数据生态圈组件(Mysql、Hive、Spark、Flink)、数据仓库、Python、前端等等。网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。需要这份系统化学习资料的朋友,可以戳这里获取。

1074

python 忽略错误_python如何忽略异常

python一般使用try…except…处理异常。try:#可能会出现异常的代码,放在try下code1#如果try内部任意一行代码出现异常,#直接跳转至except,执行except下代码code2except:code3code4此方法只要有一个异常,程序就不继续执行了。当循环中出现异常时,如何跳过循环中的异常继续执行。比如当我move一个文件的时候,如果目...

weixin_28921621的博客 3491
上一篇: python学习--关注容易被忽略的知识点--(四)函数式编程
下一篇: Python数据结构与算法(一)列表和元组
lingpy
博客等级 码龄9年 198粉丝 59原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lingpy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值