python学习—捌—类

目录

 

零、类

类的创建和使用

根据类创建实例

壹、使用类和实例

Fruit 类

给属性指定默认值

修改属性值

 贰、继承

子类的方法 __init__()

为子类定义属性和方法

 叁、导入类

导入单个类

在一个模块中存储多个类

其他

肆、python 标准库

模块 random

简单案例—猜数游戏


零、类

面向对象编程是一种十分有效的办法。在面向对象编程中,编写表示世界中的事物和情景的类,并基于这些类来创建对象。

根据类创建对象叫做类的实例化。

类的创建和使用

使用类几乎可以模拟任何东西。

来编写一个表示小狗的简单类 Dog,表示任何小狗。绝大部分宠物狗都有名字和年龄,并且他们都会打滚和蹲下。绝大部分小狗都具备以上两种信息(名字和年龄)和两种行为(打滚和蹲下),Dog 类将包含这些内容。

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

	def sit(self):
		print(f"{self.name} is sitting now.")

	def roll_over(self):
		print(f"{self.name} is rolled over.")

 首先,一开始定义了一个名为 Dog 的类,在 python 中,约定首字母大写的名称指的是类。

__init__() 方法:类中的函数称为方法,与之前的函数唯一重要的差别就是调用方法的方式。__init__() 是一个特殊方法,当你根据 Dog 类创建新实例时,python 都会自动运行这个方法。开头和末尾都有下划线是为了避免与普通方法发生名称冲突。_init_() 方法定义包含 self、name、age 三个形参,self 必不可少并且必须排在其他形参之前,这是因为 python 在调用这个方法创建 Dog 实例时,会自动传入实参 self。我们将通过实参向 Dog() 传递名字和年龄,self 会自动传递,因此不需要传递他。每当根据 Dog 类创建实例时,都只需给最后两个形参(name 和 age)提供值。

再往下,self.name 和 self.age,两个变量都有前缀 self。以 self 为前缀的变量可供类中所有方法使用,可以通过任何实例来访问。如此可以通过实例访问的变量称为属性。

Dog 类中还定义了两个方法,sit() 和 roll_over(),这些方法执行时不需要额外的信息,因此他们只有一个形参 self

根据类创建实例

可将类视为有关如何创建实例的说明。Dog 类是一系列说明,让 python 知道如何创建表示特定小狗的实例。

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

	def sit(self):
		print(f"{self.name} is sitting now.")

	def roll_over(self):
		print(f"{self.name} is rolled over.")

my_dog = Dog('tutu',2)
print(f"My dog's name is {my_dog.name}.")
print(f"My dog is {my_dog.age} years old.")

结果:

注意:一个很重要很重要的东西,init 两边各有两个 _

我们使用了之前定义的 Dog 类,主程序处第一行先是创建一条小狗,名字是 tutu,年龄是 2。python遇到这行代码,调用 Dog 类的方法 __init__() 创建一个表示特定小狗的实例,并使用提供的值赋给 name 和 age。然后,python 返回这个实例,并赋给 my_dog

命名约定:通常可以认为首字母大写的名称为类,小写的名称指的是根据类创建的实例

访问属性:访问实例的属性,可使用句点表示法。比如上述例子中使用了 my_dog.name 来访问 my_dog 的属性 name 的值。这样能够很好的表示,比如 my_dog.name 表示 python 先找到实例 my_dog,再查找与该实例相关联的属性 name。

调用方法:创建实例后,就能使用句点表示法来调用 Dog 类中定义的任何方法了。比如让小狗蹲下和打滚

调用方法时,可指定实例的名称(my_dog)和调用的方法,并用句点分隔。遇到代码 my_dog.sit() 时,python 在类 Dog 中查找方法 sit() 并运行其代码。

class Dog:
	--snip--

my_dog = Dog('tutu',2)
my_dog.sit()
my_dog.roll_over()

结果:

创建多个实例

实例不是只有一个,我们可以创建多个实例,比如再创建一个 her_dog

class Dog:
    --snip--

my_dog = Dog('tutu',2)
my_dog.sit()
her_dog = Dog('lala',3)
her_dog.roll_over()

结果:

壹、使用类和实例

可以使用类来模拟现实生活中的很多情景。

Fruit 类

现在编写一个有关水果的类。

class Fruit:
	def __init__(self,breed,quantity):
		self.breed = breed
		self.quantity = quantity
	def describ_fruit(self):
		print(f"the {self.breed} have {self.quantity} kg.")

add_fruit = Fruit('apple',20)
add_fruit.describ_fruit()

结果:

给属性指定默认值

我们在创建实例时,有些属性无需通过形参定义,在方法 __init__() 中为其指定默认值即可。

我们添加一个名为 time 的属性,其初始值为 1,表示水果送来 1 天了,并且再添加一个 read_time() 的方法,用于读取水果送来的时间。

class Fruit:
	def __init__(self,breed,quantity):
		self.breed = breed
		self.quantity = quantity
		self.time = 1
	def describ_fruit(self):
		print(f"the {self.breed} have {self.quantity} kg.")
	def read_time(self):
		print(f"It's been here for {self.time} days.")

add_fruit = Fruit('apple',20)
add_fruit.describ_fruit()
add_fruit.read_time()

结果:

结果显示正确。但是并不是所有的水果都是刚刚送来的,有的可能已经送来好几天了,所以需要修改该属性的值。

修改属性值

直接修改属性值

这是最简单的办法,我们可以直接修改属性的值。

class Fruit:
	--snip--

add_fruit = Fruit('apple',20)
add_fruit.describ_fruit()

add_fruit.time = 2
add_fruit.read_time()

结果:

add_fruit.time = 2,这行代码让 python 在实例 add_fruit 中找到属性 time,并将其值设置为 2

通过方法修改属性的值

如果有方法能替你更新属性,就无需直接访问属性,而可将值传递给方法,由它在内部进行更新。

class Fruit:
	
        --snip--
	
	def update_time(self,days):
		self.time = days

add_fruit = Fruit('apple',20)
add_fruit.describ_fruit()

add_fruit.update_time(3)
add_fruit.read_time()

结果:

我们在类中添加了新方法 update_time(),这个方法接受一个值,并将其赋给 self.time,然后在后面调用这个方法并为它提供实参

通过方法对属性值进行递增

我们卖水果,随着一天过去,应该给时间增加一天,而不是每天都为他设置新值。为此,我们可以定义一个方法

class Fruit:
	
        --snip--
	
        def addday_time(self):
		self.time += 1
add_fruit = Fruit('apple',20)
add_fruit.describ_fruit()

for i in range(9):
	add_fruit.addday_time()
add_fruit.read_time()

结果:

 贰、继承

编写类时,并不一定非要从无到有,如果要编写的类有另一个现成的特殊版本,我们就可以使用继承 ,一个类继承另一个类,就会自动获得另一个类的所有属性和方法。原有的类称为父类,而新类称为子类,子类继承了父类所有的属性和方法,同时还可以定义自己的属性和方法。

子类的方法 __init__()

在既有类基础上编写新类时,通常要调用父类的方法 __init__()。这将初始化在父类 __init()__() 方法中定义的所有属性,从而让子类包含这些属性。

我们来看一下进口水果的这个例子

class Fruit:
	def __init__(self,breed,quantity):
		self.breed = breed
		self.quantity = quantity
		self.time = 1
	def describ_fruit(self):
		print(f"the {self.breed} have {self.quantity} kg.")
	def read_time(self):
		print(f"It's been here for {self.time} days.")
	def update_time(self,days):
		self.time = days
	
class Imported_Fruit(Fruit):
	def __init__(self,bread,quantity):
		super().__init__(bread,quantity)

add_fruit = Imported_Fruit('banana',100)
add_fruit.describ_fruit()

结果:

创建子类时,父类必须包含在当前文件中,且位于子类前面。然后定义子类 Imported_Fruit,定义子类时必须在圆括号内指定父类的名称。方法 __init__() 接受创建 Fruit 实例所需的信息。super() 是一个特殊函数,让你能够调用父类的方法。

为子类定义属性和方法

继承之后,我们就可以添加区分子类和父类所需的新属性和新方法了。

下面我们添加一个属性,进口国家。

class Fruit:
    --snip--

class Imported_Fruit(Fruit):
	def __init__(self,breed,quantity):
		super().__init__(breed,quantity)
		self.country = 	'Vietnam'
	def from_country(self):
		print(f"the {self.breed} are from {self.country}")

add_fruit = Imported_Fruit('banana',100)
add_fruit.describ_fruit()
add_fruit.from_country()

结果:

我们在子类中新添加了属性 self.country,并设置初始值为 Vietnam,根据 Import_Fruit 类创建的所有实例都包含该属性,但所有 Fruit 实例都不包含它。

之后又添加了一个名为 from_country() 的方法,打印产地信息。

当我们真正在使用时,你可能会发现,随着你代码越写越多,你给类添加的细节也就越来越多,属性和方法清单以及文件都越来越长,此时我们就可以将类的一部分提取出来作为一个独立的类,将一个大类拆分成多个协同工作的小类。

叁、导入类

导入单个类

我们将 Fruit 类单独存放在文件中,并命名为 fruit.py,模块 fruit.py 如下代码所示,里面只包含 Fruit 类代码

class Fruit:
	def __init__(self,breed,quantity):
		self.breed = breed
		self.quantity = quantity
		self.time = 1
	def describ_fruit(self):
		print(f"the {self.breed} have {self.quantity} kg.")
	def read_time(self):
		print(f"It's been here for {self.time} days.")
	def update_time(self,days):
		self.time = days

然后我们创建另一个文件,在其中导入 Fruit 类并创建其实例。

from fruit import Fruit

add_fruit = Fruit('apple',20)
add_fruit.describ_fruit()

结果:

import 语句让 python 打开文件 fruit,并导入其中的 Fruit 类,这样就能使用 Fruit 类。

导入类是一种十分有效的编程方式,如此一来,主程序就显得十分简练,并且配合有意义的类名和实例名,能够很清楚的读懂代码的意义。

在一个模块中存储多个类

我们可以根据需要在一个模块中存储任意数量的类。我们将之前所写的 Imported_Fruit 类也加入 fruit 中。

class Fruit:
	--snip--

class Imported_Fruit(Fruit):
	def __init__(self,breed,quantity):
		super().__init__(breed,quantity)
		self.country = 	'Vietnam'
	def from_country(self):
		print(f"the {self.breed} are from {self.country}")

然后,我们就可以导入 Imported_Fruit 类,并创建其相关实例

from fruit import Imported_Fruit

add_fruit = Imported_Fruit('banana',100)
add_fruit.describ_fruit()

add_fruit.from_country()

结果:

其他

一个模块中导入多个类时,用逗号分隔各个类即可,导入相关类后,就可以创建相对应的实例。

导入模块中所有类时,应使用 from 文件名 import *

在模块中可以导入另一个模块

可以使用 as 为类及模块改名

肆、python 标准库

python 标准库是一组模块,我们已经安装的 python 都包含。说的简单点,标准库就是优秀的程序员写好的模块,你可以直接使用。

模块 random

randint() 会随机返回一个位于这两个整数(含)之间的整数

>>> from random import randint
>>> randint(1,6)
6
>>> randint(1,6)
2

 choice() 会随即返回一个列表或元组中的一个元素

>>> from random import choice
>>> name = ['lisa','tom','jerry']
>>> choice(name)
'tom'

简单案例—猜数游戏

只是个雏形,比较简陋,可自行扩展

from random import randint
print("猜数游戏,我想一个100以内的数字,来猜猜我想的数字是多少吧")
guess_num = randint(0,99)
sum = 0
while 1:
	enter_num = int(input("输入你猜的数字"))
	if enter_num < guess_num:
		print("猜小了")
		sum += 1
		
	elif enter_num > guess_num:
		print("猜大了")
		sum += 1
		
	elif enter_num == guess_num:
		sum += 1
		print(f"猜对了,你一共猜了{sum}次")
		break

 

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值