Python面向对象

Python是一种面向对象的编程语言,因此它支持面向对象编程(OOP)。面向对象编程是一种程序设计方法,它将数据和行为打包成对象。对象是类的实例,而类是具有相似属性和行为的一组对象的抽象。在Python中,我们可以使用类来创建对象,并且可以定义它们的属性和方法。

什么是面向对象

  • 面向对象的官方解释

“把一组数据结构和处理它们的方法组成对象(object),把相同行为的对象归纳为类(class),通过类的封装(encapsulation)隐藏内部细节,通过继承(inheritance)实现类的特化(specialization)和泛化(generalization),通过多态(polymorphism)实现基于对象类型的动态分派。”

  • 知乎上比较有趣的解释

一句话说明什么是面向对象?你个士鳖,你们全家都是士鳖!

好像有人说过这样的话,当头棒喝的方式虽然情感上不易接受,但记忆效果十分显著。

好吧,如果你觉得“土鳖”实在难听也不能准确定位你的档次,你可以自行将其替换为“土豪”,

whatever.

面向对象思想有三大要素:封装、继承和多态。

  • 封装:不管你是土鳖还是士豪,不管你中午吃的是窝头还是鲍鱼,你的下水都在你肚皮里,别人看不到你中午吃了啥,除非你自己说给他们听 (或者画给他们看,whatever);
  • 继承:刚说了,你个士鳖/豪,你们全家都是士鳖/豪。冰冻三尺非一日之寒,你有今天,必定可以从你爸爸爷爷那里追根溯源。正所谓虎父无犬子,正恩同学那么狠,他爹正日就不是什么善茬,更甭说他爷爷日成,明白了吗?
  • 多态:哲学家说过,世上不会有两个一模一样的双胞胎。即使你从你父亲那里继承来的士鳖l豪气质,也不可能完全是从一个模子里刻出来的,总会有些差别。比如你爸喜欢蹲在门前吃面,你喜欢骑在村口的歪脖子树上吃,或者反过来。当然,也可能令尊爱吃龙虾鲍鱼时旁边有几个艺校小女生喝酒唱歌助兴,你可能更喜欢弄个街舞乐队来吹拉弹唱。
  • 总结:面向对象编程的三大核心:封装、继承、多态

Python中面向对象中的重要概念

  1. 类(Class):类是一个模板或蓝图,它定义了一组属性和方法,用于创建对象。类是面向对象编程的核心概念之一,它描述了对象应该具有的特征和行为。
  2. 对象(Object):对象是类的实例,它是具有特定属性和方法的实体。每个对象都有其自己的数据和行为。
  3. 属性(Attribute):属性是对象的数据成员,它们是类定义中声明的变量。属性用于存储和描述对象的状态。
  4. 方法(Method):方法是对象的函数成员,它们是类定义中声明的函数。方法用于执行操作并更改对象的状态。
  5. 继承(Inheritance):继承是一种面向对象编程的概念,它允许开发人员创建一个新类,该类继承了现有类的属性和方法。继承允许子类重用父类的代码,从而减少了代码的重复性。
  6. 多态(Polymorphism):多态是一种面向对象编程的概念,它允许开发人员使用相同的接口来处理不同类型的对象。多态使代码更加灵活和可扩展。
  7. 封装(Encapsulation):封装是一种面向对象编程的概念,它允许开发人员隐藏对象的内部实现细节。封装通过将对象的状态和行为隐藏在类中,以使其对外部不可见,从而提高了代码的可维护性和安全性。

Python中面向对象的基本实现

类与对象

类是一种自定义数据类型,它可以包含属性和方法。对象是类的一个实例,通过实例化类来创建。在Python中,可以使用class关键字定义一个类。

class Person:def __init__(self, name, age):self.name = nameself.age = agedef say_hello(self):print(f"Hello, my name is {self.name} and I am {self.age} years old.")

在这个示例中,我们定义了一个Person类,它有两个属性:name和age,以及一个方法sayhello(),__init()__是一个特殊的方法,它在创建对象时自动调用。

继承

继承是指一个类可以从另一个类中继承属性和方法。Python中的所有类都继承自一个基类object。可以使用super()函数调用父类的方法。

class Student(Person):def __init__(self, name, age, major):super().__init__(name, age)self.major = majordef say_hello(self):super().say_hello()print(f"I am studying {self.major}.")

在这个示例中,我们定义了一个Student类,它继承自Person类。除了name和age属性外,它还有一个major属性,并且重写了say_hello()方法。

多态

多态是指相同的方法可以在不同的类中有不同的实现。Python中的多态是基于动态类型的,这意味着可以在运行时决定要调用哪个方法。

def introduce(person):person.say_hello()person1 = Person("Alice", 25)
person2 = Student("Bob", 20, "Computer Science")introduce(person1)  # 输出 "Hello, my name is Alice and I am 25 years old."
introduce(person2)  # 输出 "Hello, my name is Bob and I am 20 years old. I am studying Computer Science."

在这个示例中,我们定义了一个introduce()函数,它接受一个Person对象作为参数,并调用它的say_hello()方法。我们创建了一个Person对象和一个Student对象,并将它们作为参数传递给introduce()函数。即使它们来自不同的类,我们仍然可以使用相同的introduce()函数来介绍它们。

关于Python面向对象中的公私属性

在 Python 中,类的属性分为公有属性和私有属性。

公有属性是指可以在类的外部访问的属性,也就是说,它们是公开的。在 Python 中,所有没有以双下划线开头的属性都是公有属性。例如:

class Person:def __init__(self, name):self.name = name  # 公有属性person1 = Person("Alice")
print(person1.name)  # 输出 "Alice"

在这个示例中,我们定义了一个Person类,它有一个公有属性name,它可以在类的外部被访问。

私有属性是指只能在类的内部访问的属性,也就是说,它们是私有的。在 Python 中,所有以双下划线开头的属性都是私有属性。例如:

class Person:def __init__(self, name, age):self.name = name  # 公有属性self.__age = age  # 私有属性person1 = Person("Alice", 25)
print(person1.name)   # 输出 "Alice"
print(person1.__age)  # 报错,私有属性不能在类的外部被访问

在这个示例中,我们定义了一个Person类,它有一个公有属性name和一个私有属性age,它们都在__init__()方法中被定义。虽然我们在类的外部可以访问公有属性name,但是访问私有属性age会报错。

私有属性的存在是为了保护类的内部实现,避免外部直接访问和修改类的属性,从而提高代码的安全性和可维护性。但是,有时候我们需要在类的外部访问私有属性,可以通过一些方法来实现,例如:

class Person:def __init__(self, name, age):self.name = name  # 公有属性self.__age = age  # 私有属性def get_age(self):return self.__agedef set_age(self, age):self.__age = ageperson1 = Person("Alice", 25)
print(person1.get_age())  # 输出 "25"
person1.set_age(30)
print(person1.get_age())  # 输出 "30"

在这个示例中,我们定义了一个get_age()方法和一个set_age()方法,用于在类的外部访问和修改私有属性__age。这种方法虽然可以让私有属性在一定程度上被访问和修改,但是不推荐过多地使用,因为会降低代码的可维护性和安全性。

Python面向对象进阶

__str()__魔法方法

在 Python 面向对象编程中,__str__()方法是一个魔法方法,用于返回对象的字符串表示形式,即对象的描述信息。这个方法可以被用于自定义对象的输出格式,方便我们在程序运行过程中更好地理解对象的属性和状态。

通常情况下,如果我们直接打印一个对象,会输出该对象所属类的名称和该对象在内存中的地址。例如:

class Person:passp = Person()
print(p)
# 输出:<__main__.Person object at 0x7f9ce0a44f28>

但是如果我们在 Person 类中定义了 __str__() 方法,就可以自定义对象的输出格式了。例如,我们有一个名为 Person 的类,其中包含了 nameage 两个属性,我们可以通过在 Person 类中定义 __str__() 方法来自定义 Person 对象的输出格式:

class Person:def __init__(self, name, age):self.name = nameself.age = agedef __str__(self):return f"Person(name={self.name}, age={self.age})"p = Person("Alice", 20)
print(p)
# 输出:Person(name=Alice, age=20)

在上面的代码中,我们重写了 Person 类的 __str__() 方法,该方法返回一个字符串,其中包含了对象的属性和属性值。当我们打印 Person 对象时,输出的就是我们定义的格式,而不是默认的类名和地址。

__slots__ 魔法方法

__slots__ 是 Python 中的一个特殊魔法方法,可以用来限制对象可以添加的属性,从而优化内存使用和访问速度。

在 Python 中,每个对象都会占用一定的内存空间,其中包括对象本身所占用的空间以及对象所包含的所有属性所占用的空间。当我们需要创建大量的对象时,就会占用大量的内存空间。为了减少这种开销,可以使用 __slots__ 来限制对象所能添加的属性,从而减少内存的使用。

使用 __slots__ 需要定义一个包含所有属性名称的列表,这些属性会被存储在对象的 __dict__ 字典中。在定义 __slots__ 时,必须包含所有需要的属性名称,否则在创建对象时会抛出 AttributeError 异常。

下面是一个示例:

class Person:__slots__ = ['name', 'age']def __init__(self, name, age):self.name = nameself.age = agep = Person("Alice", 20)
p.gender = "female" # 抛出 AttributeError 异常

在上面的代码中,我们通过 __slots__Person 类的属性限制为 nameage当要设置gender的属性时,程序就会 抛出异常。

@property装饰器

在 Python 面向对象编程中,@property 装饰器可以让我们把一个方法转换成属性,从而方便地访问对象的属性值,并且可以在访问属性值时执行一些特定的操作。

通常情况下,我们可以在类中直接定义属性来存储对象的状态,例如:

class Person:def __init__(self, name, age):self.name = nameself.age = agep = Person("Alice", 20)
print(p.name) # 输出 Alice

在上面的代码中,我们定义了 Person 类,并在类的构造函数中初始化了 nameage 两个属性。我们可以通过实例对象的属性访问方式来获取或修改这些属性的值。

但是,有时候我们希望在获取或设置属性值时执行一些特定的操作,例如限制属性值的范围或格式,或者在获取属性值时进行计算或查询操作。这时候,我们可以使用 @property 装饰器来将属性定义为方法,并在方法中实现这些特定的操作。

例如,我们可以在 Person 类中定义一个 age 属性,并使用 @property 装饰器将其定义为一个方法。在方法中,我们可以添加一些逻辑来限制 age 的取值范围:

class Person:def __init__(self, name, age):self.name = nameself._age = age@propertydef age(self):return self._age@age.setterdef age(self, value):if not isinstance(value, int) or value < 0 or value > 120:raise ValueError("Invalid age")self._age = valuep = Person("Alice", 20)
print(p.age) # 输出 20p.age = 30
print(p.age) # 输出 30p.age = 150 # 抛出 ValueError 异常

在上面的代码中,我们使用 @property 装饰器将 age 属性定义为一个方法,并添加了一个 age.setter 方法,用于设置属性值。在 age.setter 方法中,我们首先判断传入的值是否为整数,并且是否在有效的年龄范围内。如果条件不满足,就抛出 ValueError 异常。否则,就将值存储在私有属性 _age 中。

使用 @property 装饰器的另一个好处是,我们可以在方法中添加一些额外的逻辑,例如计算属性值或查询数据库,而这些逻辑对于调用者来说都是透明的。例如:

class Circle:def __init__(self, radius):self.radius = radius@propertydef area(self):return 3.14 * self.radius ** 2c = Circle(5)
print(c.area) # 输出 78.5

@property 装饰器还可以用于定义只读属性,即属性值不能被修改。我们只需要在 @property 方法上面不添加 setter 方法即可。例如:

class Person:def __init__(self, name, age):self.name = nameself._age = age@propertydef age(self):return self._agep = Person("Alice", 20)
print(p.age) # 输出 20p.age = 30 # 抛出 AttributeError 异常

在上面的代码中,我们将 age 属性定义为只读属性,因为在 @property 方法上面没有添加 setter 方法。因此,尝试修改 p.age 的值会抛出 AttributeError 异常。

总之,@property 装饰器可以让我们更方便地访问和修改对象的属性,并且可以在访问属性值时执行一些特定的操作,例如限制属性值的范围、计算属性值等等。这样,我们可以更加灵活地设计类的接口,从而使代码更加简洁、易读、易用。

Python中的三种类方法

在 Python 中,类中的方法有三种类型:实例方法、静态方法和类方法。其中,实例方法是最常用的一种,而静态方法和类方法则用得相对较少。

实例方法

实例方法使用次数较多不再赘述

静态方法

静态方法是类中的一种特殊方法,它可以在不实例化类的情况下直接被类调用。它主要用于一些工具函数的封装,这些函数既不需要访问实例属性,也不需要访问类属性,仅仅是为了封装一些通用功能而存在的。定义一个静态方法,需要在方法定义前面使用 @staticmethod 装饰器。

例如,我们可以在 Person 类中定义一个静态方法 say_hello,它打印出一条欢迎信息:

class Person:def __init__(self, name, age):self.name = nameself.age = age@staticmethoddef say_hello():print('Welcome!')

我们可以在不创建 Person 实例的情况下直接调用 say_hello 方法:

Person.say_hello()

类方法

类方法是类中的另一种特殊方法,它也可以在不实例化类的情况下直接被类调用,但它与静态方法有所不同。类方法的第一个参数通常被命名为 cls,它代表的是类本身,而不是实例。类方法通常被用来处理类级别的属性和方法,例如创建一个新的实例,或者修改一个类级别的变量。定义一个类方法,需要在方法定义前面使用 @classmethod 装饰器。

例如,我们可以在 Person 类中定义一个类方法 from_birth_year,它根据出生年份创建一个新的实例:

class Person:def __init__(self, name, age):self.name = nameself.age = age@classmethoddef from_birth_year(cls, name, birth_year):age = datetime.date.today().year - birth_yearreturn cls(name, age)

我们可以使用 from_birth_year 类方法来创建一个新的 Person 实例,而不必显式地调用类的构造函数:

person = Person.from_birth_year('Alice', 1990)
print(person.name) # 输出 'Alice'
print(person.age) # 输出 31

在上面的代码中,我们使用 from_birth_year 类方法创建了一个新的 Person 实例,并且自动计算了这个实例的年龄。

总之,静态方法和类方法在 Python 中都是比较少用到的特殊方法,但它们在一些特殊的场景下非常有用,可以提高代码的可读性和灵活性。

【Python】Python面向对象详解相关推荐

  1. Python开发技术详解PDF

    Python开发技术详解(高清版)PDF 百度网盘 链接:https://pan.baidu.com/s/1F5J9mFfHKgwhkC5KuPd0Pw 提取码:xxy3 复制这段内容后打开百度网盘手 ...

  2. Python基础知识详解 从入门到精通(八)魔法方法

    目录 Python基础知识详解 从入门到精通(八)魔法方法 什么是魔法方法 基础魔法方法(较为常用) 比较操作符 算数运算符 反运算(类似于运算方法) 增量赋值运算 一元操作符 类型转换 上下文管理( ...

  3. Python开发技术详解

    Python开发技术详解 下载地址 https://pan.baidu.com/s/1KTrk3B1sajMiPIoo3-Rhuw 扫码下面二维码关注公众号回复 100089获取分享码 本书目录结构如 ...

  4. python开发技术详解pdf下载_python开发技术详解附源码-python开发技术详解电子书pdf下载高清去水印版-精品下载...

    Python开发技术详解适合Python爱好者.大中专院校的学生.社会培训班的学生以及用Python语言进行系统管理.GUI开发.Web开发.数据库编程.网络编程的人员使用. 内容提要 Python是 ...

  5. 站长在线Python教程:Python中类定义详解

    导读:欢迎你来到站长在线的站长学堂学习Python知识,本文学习的是<Python中类定义详解>. 我们在上一节内容<Python中面向对象相关概述详解>中学习过,类是具有相同 ...

  6. python20191031_20191031:Python取反运算详解

    20191031:Python取反运算详解 取反运算:~3 == 4 1.对于数字 3 =======>转换为二进制表示为011 2.对011取反为100 3.为什么表示-4 a.计算机用补码表 ...

  7. Python字符编码详解

    Python字符编码详解 转自http://www.cnblogs.com/huxi/archive/2010/12/05/1897271.html Python字符编码详解 本文简单介绍了各种常用的 ...

  8. python的执行过程_在交互式环境中执行Python程序过程详解

    前言 相信接触过Python的伙伴们都知道运行Python脚本程序的方式有多种,目前主要的方式有:交互式环境运行.命令行窗口运行.开发工具上运行等,其中在不同的操作平台上还互不相同.今天,小编讲些Py ...

  9. windows上安装Anaconda和python的教程详解

    一提到数字图像处理编程,可能大多数人就会想到matlab,但matlab也有自身的缺点: 1.不开源,价格贵 2.软件容量大.一般3G以上,高版本甚至达5G以上. 3.只能做研究,不易转化成软件. 因 ...

  10. python变量类型-Python 变量类型详解

    变量存储在内存中的值.这就意味着在创建变量时会在内存中开辟一个空间. 基于变量的数据类型,解释器会分配指定内存,并决定什么数据可以被存储在内存中. 因此,变量可以指定不同的数据类型,这些变量可以存储整 ...

最新文章

  1. Hibernate模拟试题
  2. Json string to object debug - json字符串转Java对象的处理调试
  3. 机器学习——人工神经网络之发展历史(神经元数学模型、感知器算法)
  4. java arraycopyof_Java中System.arraycopy()和Arrays.copyOf()的区别
  5. 体积最小桌面linux,Tiny Core Linux - 体积最小的精简 Linux 操作系统发行版之一 (仅10多MB) - 蓝月网络...
  6. Python GUI设计 PythonWx
  7. 02.gcc入门(下)
  8. vue-resource插件使用
  9. 微软警告:Office 已遭IE RCE 新0day 攻击
  10. 如何优雅地计算多变量
  11. Eclipse与JDK多版本兼容性设置
  12. LOL-无双剑姬我的最爱
  13. 移动硬盘损坏,数据能恢复吗
  14. 软件是一个工程,是一个商业活动,是一个艺术,更是一门经营管理。
  15. ZK锦集:Zookeeper的下载和安装 | 真/伪集群的快速搭建| 总结的很详细
  16. 命令执行原理和利用知识点
  17. 今年的奥运会延期至2021年夏季举行,盘点一下历届奥运会数据
  18. 车联网目前在我国主要的应用市场
  19. 为什么你和同事关系处不好?
  20. 【android极光推送】—从客户端到后台,一文通吃

热门文章

  1. python量化交易之路
  2. 在分类中如何处理训练集中不平衡问题
  3. 刚柔并济,酒店机器人成为提供一次性用品的好帮手!
  4. Android APP检查设备是否为平板
  5. 使用正则替换Excel字符串
  6. 原生小程序实现阿里iconfont图标显示(保姆级图文)
  7. caffe-ssd 检测视频并保存
  8. Linux跨服务器监控文件,[转]Linux下用inotify-tool实时监控服务器文件系统
  9. 蓝税问答|今天,有幸见识了各类“住房租金”的优惠!
  10. 高性能Linux: SSD分区对齐问题