Python进阶:Python面向对象编程

我们在学习一种编程语言的时候,学会了配置集成开发环境、基本语法、基本的编程技巧,这个时候总会遇到深入学习这个编程语言的瓶颈。我在学习python编程的时候,有一段时间总是在上面的过程反复徘徊,这次狠下心,针对我遇到的第一个瓶颈——面向对象Python编程。

  • 当我们能够使用gitgithub上克隆现成的程序,进行本地开发,然后针对克隆不同的程序使用minicondadocker搭建相应的虚拟环境。
  • 然而,面对一个团队或者公司开源的成百上千的代码模块,我们如何在短时间内熟练应用?秘诀就在于对Python面向对象编程的深入理解,只有掌握了面向对象编程,我们才能充分应用Pycharm类对象操作功能,极大的方便我们完成Python的开发。

一、Python面向对象简介

Python语言设计的初衷就是一种面向对象的编程语言,因此,在Python中创建一个类和对象相对于其他语言来说是很容易的。下面我们通过了一些面向对象的一些基本术语的示例,来体会Python面向对象编程的内涵。

在这里插入图片描述
首先,给出一个 最简单的类:

# Python中定义类的关键字为`class`,如果不对类进行任何定义,
# 可以直接输入pass。
class Dog:
	pass

dog_1 = Dog()	# 创建Dog()类的第一个实例`dog_1`
dog_2 = Dog()	# 创建Dog()类的第二个实例`dog_2`

# 下面动态地给第一个实例赋予属性`name`:
d1.name = 'Xiaoliang'

# 输出第一个实例的`name`属性:
print(dog_1.name)

最简单的类的演示

二、变量

Python类变量包括:类变量和实例变量。

2.1 实例变量

上面的动态给类添加变量,在实际应用会非常不方便,如果我们能直接在类中添加Dog类的故有属性name,也称为实例属性
Python类实例变量的添加是通过__init__函数(一种构造方法)实现的,假设一个狗天生具有的实例属性包含:name(名字)、height(高度)、blood(血量)、power(攻击力),实现代码如下所示:

class Dog:
	# 构造方法,在使用`Dog`类实例化的时候,首先执行`__init__`函数
	def __init__(self, name, height, blood, power):
		# 实例化的时候,下面指令可以将定义的属性,赋值给自己;
		# `self.name`是每个实例的名字,而`=`后面的`name`
		# 是实例变量,它会根据不同的实例属性分配不同的值。
		self.name = name
		self.height = height
		self.blood = blood
		self.power = power

dog_1 = Dog('Xiaoliang', 0.6, 9, 5)	# 创建第一个实例`dog_1`
dog_2 = Dog('Xiaowang', 0.7, 7, 3)	# 创建第一个实例`dog_2`

print(dog_1); print(dog_2); print(dog_1.name); print(dog_2.name)

在`__init__`中给类加上属性

注意:类的实例变量是通过self关键字表示的self的主要作用是表明这个变量是与实例属性相关的变量。

2.2 类变量

1、给类添加类变量的方法
这里结合 实例变量 来理解 类变量,来理解类变量。比如下面的代码,这里多了一个类属性num_of_dogs

class Dog:
	num_of_dogs = 0	#类属性
	
	# 构造方法:添加实例属性,做其他的初始工作
	def __init__(self, name, height, blood, power):
		self.name = name
		self.height = height
		self.blood = blood
		self.power = power

dog_1 = Dog('Xiaoliang', 0.6, 9, 5)	# 创建第一个实例`dog_1`
dog_2 = Dog('Xiaowang', 0.7, 7, 3)	# 创建第一个实例`dog_2`

# 访问类属性的方法:
# (1)通过类名访问
print(Dog.num_of_dogs)
# (2)通过实例访问
print(dog_1.num_of_dogs)

2、访问类变量的方法

在这里插入图片描述

(1)通过类名访问Dog.num_of_dogs
(2)通过实例访问dog_1.num_of_dogs

3、修改类变量的方法
同样有两种修改方法:
(1)通过类名修改:

Dog.num_of_dogs = 10			#通过类名修改
print(Dog.num_of_dogs)
print(dog_1.num_of_dogs, dog_2.num_of_dogs)

在这里插入图片描述

产生这种结果的原因:
这是由于Dog.num_of_dogs = 10执行完了,类Dog的类属性num_of_dogs就成为了10,由于类属性的作用域在类中是全局的,所以实例dog_1dog_2在访问类属性num_of_dogs也会输出10。

(2)通过实例修改

dog_1.num_of_dogs = 10
print(Dog.num_of_dogs)
print(dog_1.num_of_dogs, dog_2.num_of_dogs)

在这里插入图片描述
通过实例修改类属性的输出结果,与通过类名修改的结果不一样,这里只有dog_1.num_of_dogs输出10,而其他的类属性仍然为0

产生这种结果的原因:
这是由于dog_1.num_of_dogs = 10执行完了,生成了dog_1实例一个实例属性num_of_dogs,所以dog_1.num_of_dogs在输出的时候首先访问的是dog_1.num_of_dogs这个实例属性,而不是类属性Dog.num_of_dogs

4、类变量的作用

类变量num_of_dogs可以用来统计类Dog创建了多少个实例dog_x。可以在类中的__init__函数实现,代码如下所示:

class Dog:
	num_of_dogs = 0
	def __init__(self, name, height, blood, power):
			......
			num_of_dogs = num_of_dogs + 1

三、方法

3.1 实例方法

除了上面在__init__函数中添加的Dog类的属性,还可以通过def函数方法添加类的方法,比Dog类不仅具有上面四中故有属性,假设它们还会说人话,下面通过def函数添加speak()方法:

class Dog:
	def __init__(self, name, height, blood, power):
		self.name = name
		self.height = height
		self.blood = blood
		self.power = power

	def speak(self):
	# 构造`speak()`方法:
	# self.xx是每个实例的属性;所以输出实例的属性,
	# 需要使用self.xx
		print(f'我是{self.name}, 身高{self.height},
					血量{self.blood}, 攻击力{self.power}')

dog_1 = Dog('Xiaoliang', 0.6, 9, 5)	# 创建第一个实例`dog_1`
dog_2 = Dog('Xiaowang', 0.7, 7, 3)	# 创建第一个实例`dog_2`

# 下面调用一下每个实例的类方法:
print(dog_1.speak()); print(dog_2.speak())

在这里插入图片描述

3.2 类方法

假设我们有这样一个应用场景:我们不仅要能够得到一共实例化了多少个实例,还需要能够输出所有实例的对象,使用类方法(标志符为@classmethod)解决该问题的程序如下所示:

class Dog:
	# 首先定义一个类列表变量,用于存放类实例
	dogs = []

	# 构建一个类方法用于统计一共有多少个实例对象
	@classmethod		#这个关键字表示下面的函数为类方法
	def num_of_dogs(cls):		# cls表示输入为一个类对象
		return len(cls.dogs)

	def __init__(self, name)
		self.name = name
		# 下面指令实现:每次实例化一个实例时,就将这个实例放入
		# 类变量dogs[]列表中。注意:`self`表示当下的实例对象
		Dog.dogs.append(self)

dog_1 = Dog('Xiaoliang'); dog_2 = Dog('Xiaowang')
dog_3 = Dog('Xiaoli'); 		dog_4 = Dog('Xiaozhao')

# 使用类名调用Dog类的类方法num_of_dogs
print(Dog.num_of_dogs)
# 当然我们也可以使用实例来调用类方法num_of_dogs
print(dog_1.num_of_dogs)

在这里插入图片描述

注意:类方法不可以访问实例变量,也就是跟self相关的变量,它只可以访问类变量,所以类方法的设计只是针对类的。

3.3 静态方法

实例方法是针对实例变量(以self标志)设计的方法,而类方法是针对类变量(以cls标志)进行设计的方法。但是在实际中,有时我们需要设计一种类方法既不对实例变量进行处理,也部队类变量进行处理,这就是所谓的 静态方法,其标志符为@staticmethod。比如我们要在类中添加一个解释性语言:

class Dog:
	@staticmethod
	def description()
		print("This is a Dog class!")

	def __init__(self, name):
		self.name = name

四、面向对象三大特征

4.1 继承

虽然,前面设计Dog类方法,实例化变量有:nameheightbloodpower和类方法speak()。但是对于下图所示,对于不同类型的狗,它们具Dog的各种属性,但是它们又有自己的属性和方法。

宠物狗:具有price属性和play()方法
牧羊犬:具有num_of_sheeps属性和protect()方法
警犬:具有ability属性和detect()方法

由此仅仅使用Dog类并不能很好的表征所有的狗对象,所以我们需要引入面向对象编程的一个非常重要的概念——类的继承。使用类的继承,我们就可以在Dog类方法上,实现对宠物狗、牧羊犬、警犬的表征。下面以宠物狗为例,解释类的继承,代码如下所示:

class Dog:
	def __init__(self, name, height, power):
		self.name = name
		self.height = height
		self.power = power

	def speak(self):
		print(f'我是{self.name}, 身高{self.height}, 攻击力{self.power}')

# 在宠物狗类PetDog后面加上一个括号,内部写入父类Dog
# 这样就实现了继承了Dog类的PetDog类:
class PetDog(Dog)# 对于宠物狗的独有实例属性price,需要定义在
	# __init__()函数中定义
	def __init__(self, name, height, power, price):
		# super()关键字表示PetDog类继承父类的参数!
		super().__init__(name, height, power)
		# 执行完上面的指令,下面只需要指配宠物狗类PetDog
		# 独有的实例变量price即可。
		self.price = price

# 下面创建一个宠物狗实例
pet_dog = PetDog('Xiaoxin', 0.6, 1, 10000)
# 基于PetDog类创建的pet_dog实例,由于super()函数的作用,
# 也继承了父类的name、height、power实例变量,当然,它也
# 具有自己特有的实例变量。
print(pet_dog.price, pet_dog.name, pet_dog.height, pet_dog.power)
# pet_dog同样也继承了父类的speak()方法!
pet_dog.speak()

在这里插入图片描述

4.2 封装

封装就是只能在类内部访问,外部访问属性或方法会报异常,python中的封装很简单,只要在属性前面或方法名前加上两个下划线就可以,这样就完成了属性和方法的私有化,也就是封装。其实Python语言并没有严格意义上的私有属性,即便是类中定义了私有属性,我们也可以通过类方法输出结果。

下面给出一个Python类的封装例子,其中实例变量price被设置成私有属性,但是我们可以通过get(self)类方法输出私有属性;另外设置一个私有类函数secret_language,并设置一个共有类方法speak

class Dog:
	def __init__(self, name, price):
		self.name = name
		# 私有实例变量
		self.__price = price

	# 定义一个类方法,外部可以调用该类方法输出私有实例变量
	def get(self):
		print(self.__price)
	
dog_1 = Dog("Xiaoliang", 1000)

print(dog_1.name)			# 共有变量正常输出“Xiaoliang”
print(dog_1.__price)		# 私有实例变量不能被外部直接输出
print(dog_1.get())			# 正常输出私有实例变量`price`的值

验证输出结果如下图所示:

在这里插入图片描述

4.3 多态

Python中本质上是没有真正多态这种思路,只是形式上有这样一个多态的思路。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

嵌入式技术

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

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

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

打赏作者

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

抵扣说明:

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

余额充值