python中的类

目录

一、创建和使用类

二、使用类和实例

三、继承

四、导入类

五、python标准库

六、类编码风格


根据类来创建对象称为实例化

一、创建和使用类

使用类几乎可以模拟任何东西。编写一个表示小狗的简单类Dog,它表示的不是特定的小狗,而是任何小狗。大多数小狗具备两项信息(名字和年龄)和两种行为(蹲下和打滚),

Dog类将包含。

1.创建Dog类

:首字母大写,类定义中没有圆括号,因为要从空白创建这个类。方法:类中的函数。

class Dog:
	"""一次模拟小狗的简单尝试"""
	def __init__(self,name,age):  #以属性的方式存储名字和年龄  
		"""初始化属性name和age"""
		self.name = name
		self.age = age
	def sit(self):                       
		"""模拟小狗收到命令时蹲下"""
		print(f"{self.name} is now sitting.")
	def roll_over(self):
		"""模拟小狗收到命令时打滚。"""
		print(f"{self.name} rolled over!")

方法__init__( )

方法__init__( )是个特殊的方法,开头和末尾各有两个下划线,避免python默认方法和普通方法发生名称冲突,否则用类来创建实例时,不会自动调用这个方法。方法__init__( )中包含三个参数,self、nameage形参self必不可少,且必须位于最前面。

Python调用这个方法来创建Dog实例时,每个与实例相关联的方法调用都自动传递实参self。创建Dog实例时,Python将调用Dog类的方法__init__(),只需通过实参向Dog()传递名字和年龄,self会自动传递

self.name = name、self.age = age,定义的两个变量都有前缀self,以self为前缀的变量可供类中所有的方法使用,可通过类的任何实例来访问。通过实例来访问的变量称为属性

方法sit( )和方法roll_over( )执行时不需要额外信息,故只有一个形参self

2.根据类来创建实例

可将类作为创建实例的说明。通常用首字母大写的名称来表示类(Dog),小写的字母是根据类创建的实例(my_dog)。首先要在实例和类之间建立关联

class Dog:
	"""一次模拟小狗的简单尝试"""
	def __init__(self,name,age):   
		"""初始化属性name和age"""
		self.name = name
		self.age = age
	def sit(self):               
		"""模拟小狗收到命令时蹲下"""
		print(f"{self.name} is now sitting.")
	def roll_over(self):
		"""模拟小狗收到命令时打滚。"""
		print(f"{self.name} rolled over!")
my_dog = Dog('Willie',6)    #首先在实例与类之间建立关联   使用实参调用类中的方法_init_,方法_init_创建一个小狗的实例,实例赋给变量my_dog
print(f"My dog's name is {my_dog.name}.")
print(f"My dog's name is {my_dog.age}.")
My dog's name is Willie.
My dog's name is 6.

a.访问属性 在实例中用实例+.属性(my_dog.name),在 类中用self+.属性(self.name)

访问实例的属性,可使用句点表示法。python先找到实例,再查找相关联的属性name 实例+.属性;在Dog类中引用这个属性时,使用的是self.name self+.属性

my_dog.name

b.调用方法:实例名称+.方法

根据类创建实例后,可用句点表示法来调用类中定义的任何方法。 

class Dog:
	def __init__(self,name,age):
		self.name = name
		self.age = age
	def sit(self):
		print(f"{self.name} is now sitting.")
	def roll_up(self):
		print(f"{self.name} rolled over!")
my_dog = Dog('Willie',6)
my_dog.sit()          #python在类Dog中查找方法sit()并运行其代码
my_dog.roll_up()
Willie is now sitting.
Willie rolled over!

c.创建多个实例

可按需求根据类创建任意数量的实例,条件是每个实例粗出在不同的变量中。

class Dog:
	def __init__(self,name,age):
		self.name = name
		self.age = age
	def sit(self):
		print(f"{self.name} is now sitting.")
	def rolled_up(self):
		print(f"{self.name} rolled over!")
my_dog = Dog('Willie',6)
your_dog = Dog('Lucy',3)
print(f"My dog's name is {my_dog.name}.")
print(f"My dog is {my_dog.age} years old.")
my_dog.sit()
print(f"\nYour dog's name is {your_dog.name}.")
print(f"Your dog is {your_dog.age} years old.")
your_dog.sit()
My dog's name is Willie.
My dog is 6 years old.
Willie is now sitting.

Your dog's name is Lucy.
Your dog is 3 years old.
Lucy is now sitting.

二、使用类和实例

类编写好后,主要是根据类创建实例。常做的就是修改实例的属性,可直接修改实例的属性,也可编写方法以特定的方式修改。在函数体中如果没有print,就会出现return,除去__init__特殊方法

class Car:
	def __init__(self,make,model,year):
		self.make = make
		self.model = model
		self.year = year        #self.make self.model self.year才是变量名
	def get_descriptive_name(self):
		long_name = f"{self.year} {self.make} {self.model}"
		return long_name.title()
my_new_car = Car('audi','a4',2019)  #实例中的顺序要和方法中的__init__保持一致
print(my_new_car.get_descriptive_name())
2019 Audi A4

1.给属性指定默认值

创建属性时,有些属性无需形参来定义,可在方法__init__( )中指定默认值。

class Car:
	def __init__(self,make,model,year):  
		self.make = make
		self.model = model
		self.year = year
		self.odometer_reading = 0    #在类中指定默认值,无需在形参中出现
	def get_descriptive_name(self):
		long_name = f"{self.year} {self.make} {self.model}"
		return long_name.title()
	def read_odometer(self):
		print(f"This car has {self.odometer_reading} miles on it.")
my_new_car = Car('audi','a4',2019)
print(my_new_car.get_descriptive_name())
my_new_car.read_odometer()
2019 Audi A4
This car has 0 miles on it.

2.修改属性的值

可以直接通过实例修改,可通过方法进行设置,可通过方法进行递增(增加特定的值)。

a.直接修改属性的值:直接访问属性修改  实例+.属性=另一个值

class Car:
	def __init__(self,make,model,year):
		self.make = make
		self.model = model
		self.year = year
		self.odometer_reading = 0
	def get_descriptive_name(self):
		long_name = f"{self.year} {self.make} {self.model}"
		return long_name.title()
	def read_odometer(self):
		print(f"This car has {self.odometer_reading} miles on it.")
my_new_car = Car('audi','a4',2019)
print(my_new_car.get_descriptive_name())
my_new_car.odometer_reading = 36    #让python在实例my_new_car中找到属性odometer_reading,修改属性值
my_new_car.read_odometer()
2019 Audi A4
This car has 36 miles on it.

b.通过方法修改:用方法来更新属性,将值传递给方法,在内部进行更新。

class Car:
	def __init__(self,make,model,year):
		self.make = make
		self.model = model
		self.year = year
		self.odometer_reading = 0
	def get_descriptive_name(self):
		long_name = f"{self.year} {self.make} {self.model}"
		return long_name.title()
	def read_odometer(self):
		print(f"This car has {self.odometer_reading} miles on it.")
	def update_odometer(self,mileage):     #在类中所有的方法(函数)首个形参必须都要为self,若还有其他运算,可添加其他形参 
		self.odometer_reading = mileage    #将mileage的值赋给self.odometer_reading,不一定要返回return
my_new_car = Car('audi','a4',2019)
print(my_new_car.get_descriptive_name())
my_new_car.update_odometer(36)             #调用update_odometer(),并提供实参36
my_new_car.read_odometer()

对方法update_odometer()进行拓展,禁止将里程表读书往回调,控制用户修改属性值,但仍可以通过直接修改属性来修改。

class Car:
	def __init__(self,make,model,year):
		self.make = make
		self.model = model
		self.year = year
		self.odometer_reading = 0
	def get_descriptive_name(self):
		long_name = f"{self.year} {self.make} {self.model}"
		return long_name.title()
	def read_odometer(self):
		print(f"This car has {self.odometer_reading} miles on it.")
	def update_odometer(self,mileage):
			if mileage > self.odometer_reading:  #修改属性前检查指定的读数是否合理
				self.odometer_reading = mileage  #对类中方法__init__()方法中变量的使用都应用等号左侧(包含self)
			else:
				print("You can'nt roll back an odometer!")	
my_new_car = Car('audi','a4',2019)
print(my_new_car.get_descriptive_name())
my_new_car.update_odometer(36)
my_new_car.read_odometer()

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

将属性值递增特定的量,不是将其设为全新的值。

class Car:
	def __init__(self,make,model,year):
		self.make = make
		self.model = model
		self.year = year
		self.odometer_reading = 0
	def get_descriptive_name(self):
		long_name = f"{self.year} {self.make} {self.model}"
		return long_name.title()
	def read_odometer(self):
		print(f"This car has {self.odometer_reading} miles on it.")
	def update_odometer(self,mileage):
			if mileage > self.odometer_reading:
				self.odometer_reading = mileage  #对类中方法__init__()方法中变量的使用都应用等号左侧(包含self)
			else:
				print("You can'nt roll back an odometer!")	
	def increment_odometer(self,miles):     #在类中添加方法,对值进行递增
		self.odometer_reading += miles      #对self.odometer_reading增加miles的值
my_new_car = Car('audi','a4',2019)
print(my_new_car.get_descriptive_name())
my_new_car.update_odometer(23_500)
my_new_car.read_odometer()
my_new_car.increment_odometer(300)
my_new_car.read_odometer()
2019 Audi A4
This car has 23500 miles on it.
This car has 23800 miles on it.

三、继承

若编写的类是现成类的一个特殊版本,可使用继承。B类继承A类时,将获得A类所有的属性和方法,还可以定义自己的属性高和方法。A类称为父类,B类称为子类。

1.子类的方法__init__()

创建子类—圆括号内得包括父类名字;定义特殊方法def __init__(属性);调用父类方法super()__init__(实际属性);实例;打印输出。

super( )是一个特殊函数,能够调用父类的方法。父类也称为超类,名称由此而来。

class Car:                 #创建子类,父类必须在前面
	def __init__(self,make,model,year):
		self.make = make
		self.model = model
		self.year = year
		self.odometer_reading = 0
	def get_descriptive_name(self):
		long_name = f"{self.year} {self.make} {self.model}"
		return long_name.title()
	def read_odometer(self):
		print(f"This car has {self.odometer_reading} miles on it.")
	def update_odometer(self,mileage):
		if mileage >= self.odometer_reading:
			self.odometer_reading = mileage
		else:
			print("You can't roll back an odometer!")
	def increment_odometer(self,miles):
		self.odometer_reading += miles

class ElectricCar(Car):   #创建子类,()内包含父类的名称
	def __init__(self,make,model,year):    #方法__init__()接受创建Car所需的实例
		super().__init__(make,model,year)  #调用Car类的方法,ElectricCar实例包含这个方法中定义的所有属性
my_tesla = ElectricCar('tesla','models','2019')
print(my_tesla.get_descriptive_name())
2019 Tesla Models

2.给子类定义属性和方法

在子类中创建新属性,ElectricCar类创建的所有实例都将包含该属性,但所有Car实例将不会包括。如果一个属性和方法是任何汽车都有的,应将其加入到Car类而非ElectricCar类中。

class Car:
	def __init__(self,make,model,year):
		self.make = make
		self.model = model
		self.year = year
		self.odometer_reading = 0
	def get_descriptive_name(self):
		long_name = f"{self.year} {self.make} {self.model}"
		return long_name.title()
	def read_odometer(self):
		print(f"This car has {self.odometer_reading} miles on it.")
	def update_odometer(self,mileage):
		if mileage >= self.odometer_reading:
			self.odometer_reading = mileage
		else:
			print("You can't roll back an odometer!")
	def increment_odometer(self,miles):
		self.odometer_reading += miles

class ElectricCar(Car):
	def __init__(self,make,model,year):
		super().__init__(make,model,year)
		self.battery_size = 75      #添加新属性
	def describe_battery(self):
		print(f"This car has a {self.battery_size}-kWh battery.")
my_tesla = ElectricCar('tesla','models','2019')
print(my_tesla.get_descriptive_name())
my_tesla.describe_battery()
2019 Tesla Models
This car has a 75-kWh battery.

3.重写父类的方法

可在子类中定义一个与父类方法同名的方法,python将不会考虑父类的方法,只关注在子类中定义的相应方法。可取其精华,去其糟粕。假设Car类中有一个名为fill_gas_tank( )的方法,对全电动汽车来说毫无意义,可在子类中重写。

class ElectricCar(Car):
     --snip--
    def fill_gas_tank(self):
        print("This car doesn't need a gas tank!")

4.将实例用作属性

可以将大型的类拆分成多个协同工作的小类。不断给ElectricCar类添加细节,发现很多正对汽车电瓶的属性和方法,可将其提取出来,放到一个名为Battery的类中,并将一个Battery实例作为ElectricCar类的属性。

self.battery = Battery()       #添加了一个名为self.battery的属性,让python创建了一个新的Battery实例,并将该实例赋给属性self.battery

class Car:
	def __init__(self,make,model,year):
		self.make = make
		self.model = model
		self.year = year
		self.odometer_reading = 0
	def get_descriptive_name(self):
		long_name = f"{self.year} {self.make} {self.model}"
		return long_name.title()
	def read_odometer(self):
		print(f"This car has {self.odometer_reading} miles on it.")
	def update_odometer(self,mileage):
		if mileage >= self.odometer_reading:
			self.odometer_reading = mileage
		else:
			print("You can't roll back an odometer!")
	def increment_odometer(self,miles):
		self.odometer_reading += miles

class Battery:     #定义了一个名为Battery的类,没有继承任何类
	def __init__(self,battery_size = 75):   #方法__init__()除了self外,还提供了可选形参battery_size
		self.battery_size = battery_size
	def describe_battery(self):
		print(f"This car has a {self.battery_size}-kWh battery.")

class ElectricCar(Car):
	def __init__(self,make,model,year):
		super().__init__(make,model,year)
		self.battery = Battery()       #将实例Battery作属性self.battery
my_tesla = ElectricCar('tesla','models',2019)
print(my_tesla.get_descriptive_name())
my_tesla.battery.describe_battery()   #在实例myn_tesla中查找属性battery,并对存储在该属性中的Battery实例调用方法describe_battery()
2019 Tesla Models
This car has a 75-kWh battery.

 给Battery类再添加一个方法

class Car:
	def __init__(self,make,model,year):
		self.make = make
		self.model = model
		self.year = year
		self.odometer_reading = 0
	def get_descriptive_name(self):
		long_name = f"{self.year} {self.make} {self.model}"
		return long_name.title()
	def read_odometer(self):
		print(f"This car has {self.odometer_reading} miles on it.")
	def update_odometer(self,mileage):
		if mileage >= self.odometer_reading:
			self.odometer_reading = mileage
		else:
			print("You can't roll back an odometer!")
	def increment_odometer(self,miles):
		self.odometer_reading += miles

class Battery:
	def __init__(self,battery_size = 75):
		self.battery_size = battery_size
	def describe_battery(self):
		print(f"This car has a {self.battery_size}-kWh battery.")
	def get_range(self):
		if self.battery_size == 75:
			range = 260
		elif self.battery_size == 100:
			range = 315
		print(f"This car can go about {range} miles on a full charge.")

class ElectricCar(Car):
	def __init__(self,make,model,year):
		super().__init__(make,model,year)
		self.battery = Battery()    #将实例用做属性
my_tesla = ElectricCar('tesla','models',2019)
print(my_tesla.get_descriptive_name())
my_tesla.battery.describe_battery()
my_tesla.battery.get_range()   #通过汽车的属性来调用方法
2019 Tesla Models
This car has a 75-kWh battery.
This car can go about 260 miles on a full charge.

5.模拟实物

从较高的逻辑层面(而不是语法层面)考虑。考虑的不是Python,而是如何使用代码来表示实物。达到这种境界后,你会经常发现,对现实世界的建模方法没有对错之分。有些方法的效率更高,但要找出效率最高的表示法,需要经过一定的实践。

四、导入类

为了让文件尽可能的简洁,可将类存储在模块中,然后在主程序中导入所需的模块

模块:是后缀名为.py的文件

1.导入单个类

将Car类存储在一个名为car.py的文件中,该模块将覆盖前面使用的文件car.py。使用该模块的程序都必须使用更具体的文件名,如my_car.py。

只包含Car类的代码

"""一个可用于表示汽车的类"""
class Car:
	"""一次模拟汽车的简单尝试"""
	def __init__(self,make,model,year):
		"""初始化描述汽车属性"""
		self.make = make
		self.model = model
		self.year = year
		self.odometer_reading = 0

	def get_descriptive_name(self):
		"""返回整洁的描述信息"""
		long_name = f"{self.year} {self.make} {self.model}"
		return long_name.title()
	def read_odometer(self):
		"""打印一条信息,描述汽车的里程"""
		print(f"This car has {self.odometer_reading} miles on it.")
	def update_odometer(self,mileage):
		"""设定汽车的里程值,拒绝将里程表往回调"""
			if mileage > self.odometer_reading:
				self.odometer_reading = mileage
			else:
				print("You can'nt roll back an odometer!")	
	def increment_odometer(self,miles):
		"""将里程表读数增加指定值"""
		self.odometer_reading += miles

创建另一个文件my_car.py

import语句让python打开模块car并导入其中的Car类,就如同在这个文件中定义的一样。

from car import Car
my_new_car = Car('audio','a4',2019)
print(my_new_car.get_descriptive_name())
my_new_car.odometer_reading = 23
my_new_car.read_odometer()
2019 Audio A4
This car has 23 miles on it.

2.在一个模块中存储多个类

虽然一个模块中的类应该具有某种相关性,但可据需要在一个模块中存储任意数量的类

"""一组用于表示燃油汽车和电动汽车的类"""
class Car:
	"""一次模拟汽车的简单尝试"""
	def __init__(self,make,model,year):
		"""初始化描述汽车属性"""
		self.make = make
		self.model = model
		self.year = year
		self.odometer_reading = 0

	def get_descriptive_name(self):
		"""返回整洁的描述信息"""
		long_name = f"{self.year} {self.make} {self.model}"
		return long_name.title()
	def read_odometer(self):
		"""打印一条信息,描述汽车的里程"""
		print(f"This car has {self.odometer_reading} miles on it.")
	def update_odometer(self,mileage):
		"""设定汽车的里程值,拒绝将里程表往回调"""
		if mileage >= self.odometer_reading:
			self.odometer_reading = mileage
		else:
			print("You can'nt roll back an odometer!")	
	def increment_odometer(self,miles):
		"""将里程表读数增加指定值"""
		self.odometer_reading += miles

class Battery:
	"""一次模拟电动汽车电瓶的简单尝试"""
	def __init__(self,battery_size = 75):
		"""初始化电瓶的属性"""
		self.battery_size = battery_size
	def descriptive_battery(self):
		"""打印一条描述电瓶容量的信息"""
		print(f"This car has a {self.battery_size}-KWh battery.")
	def get_range(self):
		"""打印一条描述电瓶续航的消息"""
		if self.battery_size == 75:
			range = 260
		elif self.battery_size == 100:
			range = 315
		print(f"This car can go about {range} miles on a full charge.")

class ElectricCar(Car):
	"""模拟电动汽车的独特之处"""
	def __init__(self,make,model,year):
		"""初始化父类的属性,再初始化电动汽车特有的属性"""
		super().__init__(make,model,year)
		self.battery = Battery()

新建一个my_electric_car.py的文件,导入ElectricCar类

from car import ElectricCar
my_tesla = ElectricCar('tesla','models',2019)
print(my_tesla.get_descriptive_name())
my_tesla.battery.descriptive_battery()
my_tesla.battery.get_range()
2019 Tesla Models
This car has a 75-KWh battery.
This car can go about 260 miles on a full charge.

3.从一个模块中导入多个类

从一个模块中导入多个类时,用逗号分隔了各个类。将Car类和ElectricCar类都导入

from car import Car,ElectricCar
my_beetle = Car('volkswagen','beetle',2019)
print(my_beetle.get_descriptive_name())
my_tesla = ElectricCar('tesla','roadster',2019)
print(my_tesla.get_descriptive_name())
2019 Volkswagen Beetle
2019 Tesla Roadster

4.导入整个模块

可以先导入整个模块,再用句点表示法访问需要的类。因为创建实例的代码都包含模块名,所以不会与当前文件使用的任何名称发生冲突。 从大到小

import car
my_beetle = car.Car('volkswagen','beetle',2019)
print(my_beetle.get_descriptive_name())
my_tesla = car.ElectricCar('tesla','roadster',2019)
print(my_tesla.get_descriptive_name())
2019 Volkswagen Beetle
2019 Tesla Roadster

5.导入模块中所有的类

可使用语法  from module_nameimport *

不推荐:a.只看文件开头的import语句,就能清楚的知道程序使用 哪些类    b.可能引发名称的迷惑,如果不小心导入了一个与程序文件中其他东西同名的类,将引发难以诊断的错误.

若需从一个模块中导入很多类时,可使用4.导入整个模块的方式,即module_name.ClassName语法,可清楚知道哪些地方使用了导入的模块,也避免导入模块中的每个类可能引发的名称冲突。

6.在一个模块中导入另一个模块

有时需要将类分散到多个模块中,以免模块太大或一个模块中存储不相关的类

ElectricCar类需要访问其父类Car,因此直接将Car类导入模块,还需更新模块car,使其只包括Car类。一个模块包含Car类(car.py),一个模块包含Battery类和ElectricCar类(electric_car.py)

from car import Car
class Battery:
	"""一次模拟电动汽车电瓶的简单尝试"""
	def __init__(self,battery_size = 75):
		"""初始化电瓶的属性"""
		self.battery_size = battery_size
	def descriptive_battery(self):
		"""打印一条描述电瓶容量的信息"""
		print(f"This car has a {self.battery_size}-KWh battery.")
	def get_range(self):
		"""打印一条描述电瓶续航的消息"""
		if self.battery_size == 75:
			range = 260
		elif self.battery_size == 100:
			range = 315
		print(f"This car can go about {range} miles on a full charge.")

class ElectricCar(Car):
	"""模拟电动汽车的独特之处"""
	def __init__(self,make,model,year):
		"""初始化父类的属性,再初始化电动汽车特有的属性"""
		super().__init__(make,model,year)
		self.battery = Battery()

可分别从每个模块中导入类

from car import Car
from electric_car import ElectricCar
my_beetle = Car('volkswagen','beetle',2019)
print(my_beetle.get_descriptive_name())
my_tesla = ElectricCar('tesla','roadster',2019)
print(my_tesla.get_descriptive_name())
2019 Volkswagen Beetle
2019 Tesla Roadster

7.使用别名

导入类时,可指定别名。如程序中创建大量电动汽车实例,需反复输入ElectricCar,繁琐,可在import语句中给ElectricCar指定一个别名。

from electric_car import ElectricCar as EC
my_tesla = EC('tesla','roadster',2019)

8.自定义工作流程

一开始让代码结构尽可能简单,先尽可能在一个文件中完成所有工作,确定正常运行后,再将类移到独立的模块中

也可正在项目开始时就尝试将类存储再模块中。

五、python标准库

python标准库时一组模块,安装的python都包含。可以使用标准库中的任何函数和类,只需在程序开头包含简单的import语句

random模块函数randint( )很有趣,将两个整数作为参数,随机返回一个位于两个数之间的参数

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

另一个函数choice( )也很有用,将列表或元组作为参数,并随机返回其中的一个元素。

>>> from random import choice
>>> players = ['charles','martina','michael','florence','eli']
>>> first_up = choice(players)
>>> first_up
'michael'

创建与安全相关的应用程序时,不要使用random,但可以创建众多有趣的项目。

六、类编码风格

与类相关的编码风格。类名应采用驼峰命名法,即类名中的每个单词的首字母大写而不使用下划线,实例名模块名用小写格式,并在单词之间加上下划线。

对于每个类,都应紧跟在类的后面包含一个文档字符串,简要描述类的功能,每个模块也应包含一个文档字符串,描述用途。

可用空行来组织代码,但不能滥用。在类中可用一个空行来分割方法,模块中可用两个空行来分割类。

需同时导入标准库的模块和自己写的模块时,先编写导入标准库模块的import语句,再添加空行,然后编写导入自己编写模块的import语句。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值