python类的封装,python对函数进行封装
本文主要详细介绍Python面向对象编程的包装艺术。本文中的示例代码非常详细,具有一定的参考价值。感兴趣的朋友可以参考一下,希望能帮到你。
00-1010 1.面向对象编程1.1面向对象的特性1.2面向对象的基本概念2。Python实现OOP2.1分析问题2.2类设计语法2.3创建对象语法3。OOP封装3.1广阔视角:封装的优势无处不在!3.2狭义:保证内部数据实现过程的完整性:4。总结。
目录
OOP (面向对象编程) 即面向对象编程。
面向对象编程是一种编码思想或一种代码组织方式.就像在编辑一篇文章时,你可以选择分段、分节的方式,使文章看起来层次分明,更容易阅读或修改。
编码时可以选择使用或不使用OOP方案。与措辞一样,使用与否对核心逻辑.没有影响
面向对象编程有自己的核心编码理论。对于任何计算机语言,如果你选择支持这个理论,则称此计算机语言支持面向对象编程. C,Java,Python…….
由于每种计算机语言的语法不同,在提供OOP实现时,语法规范会有很大的差异。此外,对于每一种语言,语法可以在OOPs基本理论的基础上扩展或限制。比如Python支持多重继承。Java语言只支持单根继承.
1. 面向对象编程
要了解OOP,的特点,可以从两个角度来解释。
广义来说,让程序像人类一样解决问题,让程序拥有人类的思维模式。
人类在解决问题时,首先应该知道哪些对象会涉及到问题域,然后深入了解每一个对象的特性或功能,,最后做出相应的决策。
比如:为班级选一名班长。
选择显示器是现实世界中的一个问题。怎样才能选择到符合要求的显示器?
1.先确定这个问题涉及的对象(这里是全班同学)。
2.然后了解每个学生的兴趣、爱好、性格……以及个人能力等。
3.从你认识的小组中找出一个认识班长标准的学生。
面向对象编程中的对象一词借鉴了现实世界中对象的概念。
狭义:OOP编码对于整个程序维护的优势。
OOP组织的代码可以使程序作为一个整体具有很高的可读性。此外,最重要的特点是它可以提高代码的复用性、安全性、可扩展性。。
任何事情都会是双面的,OOP会让代码更难理解。
1.1 OOP 特点
在OOP中有两个非常重要的概念,类和对象.
对象从何而来?
在现实世界中,我们很少考虑这个问题,在选班.
长时,不会思考学生是从哪里来的,即使思考这个问题,也会认为那是哲学家的事情。
我们不思考现实世界中的手机、电脑、电视机是怎么来的……因为我们不关心这个,我们关心的是使用它们所提供的功能。
如果我们思考一下手机是怎么出现的,则会发现:
1.首先需要工程师设计手机蓝图。
2.在工厂里根据手机蓝图进行生产(可能生产很多)。
3.用户购买手机,了解手机特性和功能,使用手机。
我们身边的诸如 电视机、洗衣机、电脑……
无不例外的需要经过这几个过程后方能来到我们的世界。
即使是人也是女娲按自己的样子创建出来的……
同理,电脑世界里不会突然冒出手机、电脑、学生……如何才能让电脑出现此类对象。一样,先设计一个蓝图,此蓝图在电脑世界我们就称其为类。
有了类之后才可以创建手机对象,有了对象后才能在程序代码中使用设计时为手机赋予功能完成程序逻辑。
现实世界设计手机蓝图时,需要设计手机的外观,如大小、形状、体重……需要赋予手机功能、如打电话、播放音乐、播放视频、上网……
在计算机的编码世界里,同样在设计类时需要为 手机类 设计外观和功能。OPP 中称外观为属性,称功能为方法。
类是蓝图,具有抽象性特征
对象是根据蓝图创建出来的个体,具有具体性、实用性特征
2. Python 实现 OOP
如需使用 OOP 理念实现程序逻辑,则需遵循如下流程:
2.1 分析问题
首先需要明确问题:如编写一个程序摸拟小狗的行为。
此问题中的对象便是小狗,所以程序中需要一只小狗。
按上所述,创建小狗之前需要设计狗类,因此需要为类的设计提供足够的信息。
分析可得在设计类时需要有小狗属性:姓名、年龄,小狗的行为:尊下、打滚。
2.2 类设计语法
class Dog():def __init__(self, name, age):
"""初始化属性name和age"""
self.name = name
self.age = age
def sit(self):
"""小狗蹲下行为"""
print(self.name.title() + " 乖乖的尊下了!")
def roll_over(self):
"""小狗打滚"""
print(self.name.title() + " 开始打滚哈!")
如上为 python 中类设计的结构语法:
- 类的函数称为方法,方法的第一个参数须是self 关键字。
- __init__方法是必须的,其方法名不得修改。 此方法会在创建对象时被自动调用,用来初始化对象数据。
- self.name 声明一个对象变量,此变量会保存对象的数据。
2.3 创建对象语法
有了类后,方可创建对象,有了对象后方可激活属性和方法。
my_dog = Dog('小雪', 6) print("小狗的名字:"+my_dog.name.title()+".") print("小狗今年"+str(my_dog.age)+" 岁了")
my_dog.sit() my_dog.roll_over()
创建小狗时,需调用和类名相同的方法,如上述的Dog( )方法,此方法也叫构造方法,此方法实质是调用了类设计中的__init__方法。所以需要传递小狗的具体姓名和年龄初始 name 和 age 变量。
调用类中的方法时,不需要为方法声明时的 self 参数传递值。
有了对象后,如需要使用此对象的数据时,可使用.运算符。如上 my_dog.name 得到小狗的姓名。
当然,在创建小狗后,也可以根据需要修改小狗的姓名和年龄。
my_dog.name=小花my_dog.age=4
同样,也可以使用 . 运算符调用类设计时的方法。调用方法也不需要为第一个参数 self 传值。
运行结果:
小狗的名字:小雪.
小狗今年6 岁了
小雪 乖乖的尊下了!
小雪 开始打滚哈!
有了类之后,可以根据此类的设计方案,创建出多个对象。每一个对象有自己的数据空间,彼此之间的数据是独立且隔离的。
my_dog = Dog(小黑, 6)your_dog = Dog(小白, 3)
print("我的小狗的名字: "+my_dog.name.title()+".")
print("我的小狗的年龄 "+str(my_dog.age)+"岁了.")
my_dog.sit()
print("\n你的小狗的名字: "+your_dog.name.title()+".")
print("你的小狗的年龄 "+str(your_dog.age)+" 岁了.")
your_dog.sit()
如同现实世界一样。现在有了 2 只小狗,它们是独立的个体。修改其中一只狗的名字,对另一只小狗是没影响的。
我的小狗的名字: 小黑.
我的小狗的年龄 6岁了.
小黑 乖乖的尊下了!
你的小狗的名字: 小白.
你的小狗的年龄 3 岁了.
小白 乖乖的尊下了!
3. OOP 的封装性
封装性可以从 2 个角度上展开讨论:
3.1 广义角度:无处不封装
类就是一个封装体:它把数据以及对数据的相关操作方法封装在了一起。
方法也是一个封装体:封装了代码逻辑。
封装的优点!
当我们通过对象使用数据和方法时,不需要了解其中的内部细节,如此实现了设计和使用的分离,和现实世界中我们使用手机一样,不需了解手机的内部结构和细节。
开发者在使用 python 提供的模块时,不需要了解模块中的相关实现细节,直接使用其功能便可。
设计和使用的分离能加速工业软件的开发效率。
3.2 狭义角度:保证内部数据的完整性
创建一只小狗后,可以编写如下代码修改小狗的年龄。
my_dog = Dog(小雪, 6)my_dog.age=-4
显然这是不符合实际情况的,没有一只小狗的年龄可以是负 4 岁。但是,现在程序可以正常运行。
小狗今年-4 岁了
出现这样不合常理的想象,应该追究谁的责任。类的设计者还是对象使用者?
我们应该要追究类设计者的责任,就如同我刚买的手机不能充电一样,是设计者的设计缺陷引起的。
我们应该在设计类的时候提供一种内部安全检查机制,保护变量能被赋予一个正确的、可靠的值。
实施流程:
1. 在变量、方法的前面加上双下划线(__)让变量成为私有概念
python 的语法有很大的弹性。添加下划性只是一种象征性或类似于道德层面的约定。并不能真正意义上让外部不能访问。
class Dog():def __init__(self, name, age):
"""初始化属性name和age"""
self.name = name
#私有化
self.__age = age
def sit(self):
"""小狗蹲下行为"""
print(self.name.title() + " 乖乖的尊下了!")
def roll_over(self):
"""小狗打滚"""
print(self.name.title() + " 开始打滚哈!")
2. 在类中提供对应的 set 和 get 方法实现对内部变量的保护。
def get_age(self):return self.__age
# 对数据进行检查
def set_age(self, age):
if age<0:
print("小狗的年龄不可能为负数")
return
self.__age = age
3. 测试
my_dog = Dog(小雪, 6)my_dog.set_age(-4)
print("小狗的名字:"+my_dog.name.title()+".")
print("小狗今年"+str(my_dog.get_age())+" 岁了")
输出结果
小狗的年龄不可能为负数
小狗的名字:小雪.
小狗今年6 岁了
python 还有一种更优雅的解决方案。使用注解方式。
class Dog():def __init__(self, name, age):
self.name = name
# 私有属性,属性名(age)前面双下划线的名称
self.__age = age
# 实例方法
def run(self):
print("{} 在跑……".format(self.name))
# 使用 @property 定义age属性的 get 方法
@property
def age(self):
return self.__age
# 使用 @age.setter 定义 age 属性的 set 方法必须放在@property的后面
@age.setter
def age(self, age):
if age < 0:
print("小狗的年龄不能是负数")
return
self.__age = age
#实例化小狗
dog = Dog("小红", 3)
print("{0} 狗狗的年龄是 {1}".format(dog.name, dog.age))
#修改年龄
dog.age = -4
print("{0} 狗狗的年龄是 {1}".format(dog.name, dog.age))
输出结果
小红 狗狗的年龄是 3
小狗的年龄不能是负数
小红 狗狗的年龄是 3
4 . 总结
面向对象编程可以用《人类简史》中的一句话总结,人类文明的进步不一定能泽福到每一个个体。
类可以设计的很完美,但每一个对象作为个体可以有自己的命运。
封装是面向对象编程理念中最基本也是最重要的特性,没有封装便没有后续的更多。
封装可能让我们把相关联的数据与方法构建成一个逻辑上的整体,也可保护内部数据的安全性,毕竟没有数据安全性的程序是没有意义的。
本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注盛行IT软件开发工作室的更多内容!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。