《Python编程 从入门到实践》-基础知识总结8

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/liluo_2951121599/article/details/79967425

类(重要)

面向对象编程是最有效的软件编写方法之一。

基于类创建对象时,每个对象都自动具备这种通用行为,然后可根据需要赋予每个对象独特的个性。

根据类来创建对象被称为实例化,这让你能够使用类的实例。


  • 创建和使用类
  • 使用类和实例
  • 继承
  • 导入类
  • Python标准库
  • 类编码风格

一、创建和使用类

1. 创建Dog类  class Dog():

根据Dog 类创建的每个实例都将存储名字和年龄。我们赋予了每条小狗蹲下sit() 和打滚roll_over() 的能力:

[python] view plain copy
  1. class Dog():   
  2.     """一次模拟小狗的简单尝试"""  
  3.     def __init__(self, name, age):  
  4.         """初始化属性name和age"""  
  5.         self.name = name  
  6.         self.age = age  
  7.   
  8.     def sit(self):  
  9.         """模拟小狗被命令时蹲下"""  
  10.         print(self.name.title() + " is now sitting.")  
  11.   
  12.     def roll_over(self):  
  13.         """模拟小狗被命令时打滚"""  
  14.         print(self.name.title() + " rolled over!")  

(1)方法__init__()

类中的函数称为方法。__init__()是一个特殊的方法,每当你根据Dog类创建新实例时,Python都会自动运行它。在这个方法的名称中,开头和末尾各有两个下划线,这是一种约定,旨在避免Python默认方法与普通方法发生名称冲突。

我们将方法__init__() 定义成了包含三个形参:self 、name 和age 。在这个方法的定义中,形参self 必不可少,还必须位于其他形参的前面。为何必须在方法定义中包含形参self 呢?因为Python 调用这个__init__() 方法来创建Dog 实例时,将自动传入实参self 。每个与类相关联的方法调用都自动传递实参self ,它是一个指向实例本身的引用让实例能够访问类中的属性和方法。我们创建Dog 实例时,Python 将调用Dog 类的方法__init__() 。我们将通过实参向Dog() 传递名字和年龄;self 会自动传递,因此我们不需要传递它。每当我们根据Dog 类创建实例时,都只需给最后两个形参(name 和age)提供值。


另外两个函数的形参都有前缀self 。self 为前缀的变量都可供类中的所有方法使用,我们还可以通过类的任何实例来访问这些变量。self.name = name 获取存储在形参name 中的值,并将其存储到变量name 中,然后该变量被关联到当前创建的实例。self.age = age 的作用与此类似。

(2)在Python 2.7 中创建类

Python 2.7 中创建类时,需要做细微的修改—— 在括号内包含单词object :

[python] view plain copy
  1. class ClassName(object):  
  2.     --snip--  

2. 根据类创建实例    my_dog = Dog('willie'6

下面来创建一个表示特定小狗的实例:

[python] view plain copy
  1. class Dog():  
  2.     --snip--(与前相同)  
  3.   
  4. my_dog = Dog('willie'6)  
  5.   
  6. print("My dog's name is " + my_dog.name.title() + ".")  
  7. print("My dog is " + str(my_dog.age) + " years old.")  

(1)访问属性  my_dog.name

[python] view plain copy
  1. my_dog.name  
创建实例输出有关my_dog 的摘要:
[python] view plain copy
  1. My dog's name is Willie.  
  2. My dog is 6 years old.  

(2)调用方法   my_dog.sit()

[python] view plain copy
  1. class Dog():  
  2.     --snip--  
  3.   
  4. my_dog = Dog('willie'6)  
  5. my_dog.sit()  
  6. my_dog.roll_over()  
输出:

[python] view plain copy
  1. Willie is now sitting.  
  2. Willie rolled over!  

二、使用类和实例

1. Car类   class Car()

[python] view plain copy
  1. class Car():  
  2.     """一次模拟汽车的简单尝试"""  
  3.     def __init__(self, make, model, year):  
  4.         """初始化描述汽车的属性"""  
  5.         self.make = make  
  6.         self.model = model  
  7.         self.year = year  
  8.   
  9.     def get_descriptive_name(self):  
  10.         """返回整洁的描述性信息"""  
  11.         long_name = str(self.year) + ' ' + self.make + ' ' + self.model  
  12.         return long_name.title()  
  13.   
  14. my_new_car = Car('audi''a4'2016)  
  15. print(my_new_car.get_descriptive_name())#2016 Audi A4  

2. 给属性指定默认值    my_new_car = Car('audi', 'a4', 2016)

下面来添加一个名为odometer_reading 的属性(里程表),其初始值总是为0 。我们还添加了一个名为read_odometer() 的方法,用于读取汽车的里程表:

[python] view plain copy
  1. class Car():  
  2.     """一次模拟汽车的简单尝试"""  
  3.     def __init__(self, make, model, year):  
  4.         """初始化描述汽车的属性"""  
  5.         self.make = make  
  6.         self.model = model  
  7.         self.year = year  
  8.         self.odometer_reading = 0  
  9.   
  10.     def get_descriptive_name(self):  
  11.         """返回整洁的描述性信息"""  
  12.         long_name = str(self.year) + ' ' + self.make + ' ' + self.model  
  13.         return long_name.title()  
  14.   
  15.     def read_odometer(self):  
  16.         """打印一条指出汽车里程的消息"""  
  17.         print("This car has " + str(self.odometer_reading) + " miles on it.")  
  18.   
  19. my_new_car = Car('audi''a4'2016)  
  20. print(my_new_car.get_descriptive_name())  
  21. my_new_car.read_odometer()  

[python] view plain copy
  1. 2016 Audi A4  
  2. This car has 0 miles on it.  

3.修改属性的值

(1)直接修改属性的值

直接将里程表读数设置为23 : my_new_car.odometer_reading = 23  

[python] view plain copy
  1. class Car():  
  2.     """一次模拟汽车的简单尝试"""  
  3.     def __init__(self, make, model, year):  
  4.         """初始化描述汽车的属性"""  
  5.         self.make = make  
  6.         self.model = model  
  7.         self.year = year  
  8.         self.odometer_reading = 0  
  9.   
  10.     def get_descriptive_name(self):  
  11.         """返回整洁的描述性信息"""  
  12.         long_name = str(self.year) + ' ' + self.make + ' ' + self.model  
  13.         return long_name.title()  
  14.   
  15.     def read_odometer(self):  
  16.         """打印一条指出汽车里程的消息"""  
  17.         print("This car has " + str(self.odometer_reading) + " miles on it.")  
  18.   
  19. my_new_car = Car('audi''a4'2016)  
  20. print(my_new_car.get_descriptive_name())  
  21. my_new_car.odometer_reading = 23  
  22. my_new_car.read_odometer()  
--

[python] view plain copy
  1. 2016 Audi A4  
  2. This car has 23 miles on it.  

(2)通过方法修改属性的值

              my_new_car.update_odometer(23)  

[python] view plain copy
  1. class Car():  
  2.     --snip--  
  3.     def update_odometer(self, mileage):  
  4.         """将里程表读数设置为指定的值"""  
  5.         self.odometer_reading = mileage  
  6.   
  7. my_new_car = Car('audi''a4'2016)  
  8. print(my_new_car.get_descriptive_name())  
  9. my_new_car.update_odometer(23)  
  10. my_new_car.read_odometer()  
[python] view plain copy
  1. 2016 Audi A4  
  2. This car has 23 miles on it.  

(3)通过方法对属性的值进行递增

             self.odometer_reading += miles  


[python] view plain copy
  1. class Car():  
  2.     --snip--  
  3.     def update_odometer(self, mileage):  
  4.         --snip--  
  5.   
  6.     def increment_odometer(self, miles):  
  7.         """将里程表读数增加指定的量"""  
  8.         self.odometer_reading += miles  
  9.   
  10. my_used_car = Car('subaru''outback'2013)  
  11. print(my_used_car.get_descriptive_name())  
  12.   
  13. my_used_car.update_odometer(23500)  
  14. my_used_car.read_odometer()  
  15.   
  16. my_used_car.increment_odometer(100)  
  17. my_used_car.read_odometer()  
[python] view plain copy
  1. 2013 Subaru Outback  
  2. This car has 23500 miles on it.  
  3. This car has 23600 miles on it.  

三、继承

编写类时,并非总是要从空白开始。如果你要编写的类是另一个现成类的特殊版本,可使用继承 。一个类继承另一个类时,它将自动获得另一个类的所有属性和方法;原有的类称为父类 ,而新类称为子类 。子类继承了其父类的所有属性和方法,同时还可以定义自己的属性和方法。

1. 子类的方法__init__()

下面来创建一个简单的ElectricCar (电动汽车)类版本,它具备Car 类的所有功能:class ElectricCar(Car): 

[python] view plain copy
  1. class Car():  
  2.     """一次模拟汽车的简单尝试"""  
  3.     def __init__(self, make, model, year):  
  4.         self.make = make  
  5.         self.model = model  
  6.         self.year = year  
  7.         self.odometer_reading = 0  
  8.   
  9.     def get_descriptive_name(self):  
  10.         long_name = str(self.year) + ' ' + self.make + ' ' + self.model  
  11.         return long_name.title()  
  12.   
  13.     def read_odometer(self):  
  14.         print("This car has " + str(self.odometer_reading) + " miles on it.")  
  15.   
  16.     def update_odometer(self, mileage):  
  17.         if mileage >= self.odometer_reading:  
  18.             self.odometer_reading = mileage  
  19.         else:  
  20.             print("You can't roll back an odometer!")  
  21.   
  22.     def increment_odometer(self, miles):  
  23.         self.odometer_reading += miles  
  24.   
  25. class ElectricCar(Car):  
  26.     """电动汽车的独特之处"""  
  27.     def __init__(self, make, model, year):  
  28.         """初始化父类的属性"""  
  29.         super().__init__(make, model, year)  
  30.   
  31. my_tesla = ElectricCar('tesla''model s'2016)  
  32. print(my_tesla.get_descriptive_name())  

创建子类时,父类必须包含在当前文件中,且位于子类前面。定义子类时,必须在括号内指定父类的名称。方法__init__()接受创建Car 实例所需的信息。

super()是一个特殊函数,帮助Python将父类和子类关联起来。这行代码让Python调用ElectricCar的父类的方法__init__(),让ElectricCar实例包含父类的所有属性。父类也称为超类(superclass),名称super因此而得名。

除方法__init__() 外,电动汽车没有其他特有的属性和方法。当前,我们只想确认电动汽车具备普通汽车的行为:

[python] view plain copy
  1. 2016 Tesla Model S  

2. Python 2.7 中的继承

Python 2.7 中,继承语法稍有不同,ElectricCar 类的定义类似于下面这样:

[python] view plain copy
  1. class Car(object):  
  2.     def __init__(self, make, model, year):  
  3.         --snip--  
  4.   
  5. class ElectricCar(Car):  
  6.     def __init__(self, make, model, year):  
  7.         super(ElectricCar, self).__init__(make, model, year)  
  8.         --snip--  

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

让一个类继承另一个类后,可添加区分子类和父类所需的新属性和方法。

下面来添加一个电动汽车特有的属性(电瓶),以及一个描述该属性的方法。我们将存储电瓶容量,并编写一个打印电瓶描述的方法:def describe_battery(self): 

[python] view plain copy
  1. class Car():  
  2.     --snip--  
  3.   
  4. class ElectricCar(Car):  
  5.     """Represent aspects of a car, specific to electric vehicles."""  
  6.     def __init__(self, make, model, year):  
  7.     """ 
  8.     电动汽车的独特之处 
  9.     初始化父类的属性,再初始化电动汽车特有的属性 
  10.     """  
  11.         super().__init__(make, model, year)  
  12.         self.battery_size = 70  
  13.   
  14.     def describe_battery(self):  
  15.         """打印一条描述电瓶容量的消息"""  
  16.         print("This car has a " + str(self.battery_size) + "-kWh battery.")  
  17.           
  18. my_tesla = ElectricCar('tesla''model s'2016)  
  19. print(my_tesla.get_descriptive_name())  
  20. my_tesla.describe_battery()  
[python] view plain copy
  1. 2016 Tesla Model S  
  2. This car has a 70-kWh battery.  

4.重写父类方法

对于父类的方法,只要它不符合子类模拟的实物的行为,都可对其进行重写。为此,可在子类中定义一个这样的方法,即它与要重写的父类方法同名。这样,Python 将不会考虑这个父类方法,而只关注你在子类中定义的相应方法。假设Car 类有一个名为fill_gas_tank() 的方法,它对全电动汽车来说毫无意义,因此你可能想重写它。下面演示了一种重写方式: print("This car doesn't need a gas tank!")  

[python] view plain copy
  1. def ElectricCar(Car):  
  2.     --snip--  
  3.   
  4. def fill_gas_tank():  
  5.     """电动汽车没有油箱"""  
  6.     print("This car doesn't need a gas tank!")  

5.将实例用作属性

使用代码模拟实物时,你可能会发现自己给类添加的细节越来越多:属性和方法清单以及文件都越来越长。在这种情况下,可能需要将类的一部分作为一个独立的类提取出来。你可以将大型类拆分成多个协同工作的小类

例如,不断给ElectricCar 类添加细节时,我们可能会发现其中包含很多专门针对汽车电瓶的属性和方法。在这种情况下,我们可将这些属性和方法提取出来,放到另一个名为Battery 的类中,并将一个Battery 实例用作ElectricCar 类的一个属性:class Battery():  

[python] view plain copy
  1. class Car():  
  2.     """一次模拟汽车的简单尝试"""  
  3.     def __init__(self, make, model, year):  
  4.         self.make = make  
  5.         self.model = model  
  6.         self.year = year  
  7.         self.odometer_reading = 0  
  8.   
  9.     def get_descriptive_name(self):  
  10.         long_name = str(self.year) + ' ' + self.make + ' ' + self.model  
  11.         return long_name.title()  
  12.   
  13. class Battery():  
  14.     """一次模拟电动汽车电瓶的简单尝试"""  
  15.     def __init__(self, battery_size=70):  
  16.         """初始化电瓶的属性"""  
  17.         self.battery_size = battery_size  
  18.   
  19.     def describe_battery(self):  
  20.         """打印一条描述电瓶容量的消息"""  
  21.         print("This car has a " + str(self.battery_size) + "-kWh battery.")  
  22.   
  23. class ElectricCar(Car):  
  24.     """电动汽车的独特之处"""  
  25.     def __init__(self, make, model, year):  
  26.         """ 
  27.         初始化父类的属性,再初始化电动汽车特有的属性 
  28.         """  
  29.         super().__init__(make, model, year)  
  30.         self.battery = Battery()  
  31.   
  32. my_tesla = ElectricCar('tesla''model s'2016)  
  33.   
  34. print(my_tesla.get_descriptive_name())  
  35. my_tesla.battery.describe_battery()  
[python] view plain copy
  1. 2016 Tesla Model S  
  2. This car has a 70-kWh battery.  

四、导入类

随着你不断地给类添加功能,文件可能变得很长,即便你妥善地使用了继承亦如此。为遵循Python 的总体理念,应让文件尽可能整洁。为在这方面提供帮助,Python 允许你将类存储在模块中,然后在主程序中导入所需的模块。

1. 导入单个类

下面是模块car.py ,其中只包含Car 类的代码:

[python] view plain copy
  1. """一个可用于表示汽车的类"""  
  2. class Car():  
  3.     """一次模拟汽车的简单尝试"""  
  4.     def __init__(self, make, model, year):  
  5.         """初始化描述汽车的属性"""  
  6.         self.make = make  
  7.         self.model = model  
  8.         self.year = year  
  9.         self.odometer_reading = 0  
  10.   
  11.     def get_descriptive_name(self):  
  12.         """返回整洁的描述性名称"""  
  13.         long_name = str(self.year) + ' ' + self.make + ' ' + self.model  
  14.         return long_name.title()  
  15.   
  16.     def read_odometer(self):  
  17.         """打印一条消息,指出汽车的里程"""  
  18.         print("This car has " + str(self.odometer_reading) + " miles on it.")  
  19.   
  20.     def update_odometer(self, mileage):  
  21.         """ 
  22.         将里程表读数设置为指定的值 
  23.         拒绝将里程表往回拨 
  24.         """  
  25.         if mileage >= self.odometer_reading:  
  26.             self.odometer_reading = mileage  
  27.         else:  
  28.             print("You can't roll back an odometer!")  
  29.   
  30.     def increment_odometer(self, miles):  
  31.         """将里程表读数增加指定的量"""  
  32.         self.odometer_reading += miles  

下面来创建另一个文件——my_car.py ,在其中导入Car 类并创建其实例:from car import Car 

[python] view plain copy
  1. from car import Car  
  2.   
  3. my_new_car = Car('audi''a4'2016)  
  4. print(my_new_car.get_descriptive_name())  
  5.   
  6. my_new_car.odometer_reading = 23  
  7. my_new_car.read_odometer()  

[python] view plain copy
  1. <span style="font-weight:normal;">2016 Audi A4  
  2. This car has 23 miles on it.</span>  

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

Battery 和ElectricCar 都可帮助模拟汽车,因此下面将它们都加入模块car.py 中:

[python] view plain copy
  1. """一组用于表示燃油汽车和电动汽车的类"""  
  2. class Car():  
  3.     --snip--  
  4.   
  5. class Battery():  
  6.     """一次模拟电动汽车电瓶的简单尝试"""  
  7.     def __init__(self, battery_size=60):  
  8.         """初始化电瓶的属性"""  
  9.         self.battery_size = battery_size  
  10.   
  11.     def describe_battery(self):  
  12.         """打印一条描述电瓶容量的消息"""  
  13.         print("This car has a " + str(self.battery_size) + "-kWh battery.")  
  14.   
  15.     def get_range(self):  
  16.         """打印一条描述电瓶续航里程的消息"""  
  17.         if self.battery_size == 70:  
  18.             range = 240  
  19.         elif self.battery_size == 85:  
  20.             range = 270  
  21.   
  22.         message = "This car can go approximately " + str(range)  
  23.         message += " miles on a full charge."  
  24.         print(message)  
  25.   
  26. class ElectricCar(Car):  
  27.     """模拟电动汽车的独特之处"""  
  28.     def __init__(self, make, model, year):  
  29.         """ 
  30.         初始化父类的属性,再初始化电动汽车特有的属性 
  31.         """  
  32.         super().__init__(make, model, year)  
  33.         self.battery = Battery()  

现在,可以新建一个名为my_electric_car.py 的文件,导入ElectricCar 类,并创建一辆电动汽车了:

from car import ElectricCar  

[python] view plain copy
  1. from car import ElectricCar  
  2.   
  3. my_tesla = ElectricCar('tesla''model s'2016)  
  4.   
  5. print(my_tesla.get_descriptive_name())  
  6. my_tesla.battery.describe_battery()  
  7. my_tesla.battery.get_range()  
[python] view plain copy
  1. 2016 Tesla Model S  
  2. This car has a 70-kWh battery.  
  3. This car can go approximately 240 miles on a full charge.  

3.从一个模块中导入多个类  from car import Car, ElectricCar  

[python] view plain copy
  1. from car import Car, ElectricCar  
  2.   
  3. my_beetle = Car('volkswagen''beetle'2016)  
  4. print(my_beetle.get_descriptive_name())  
  5.   
  6. my_tesla = ElectricCar('tesla''roadster'2016)  
  7. print(my_tesla.get_descriptive_name())  
[python] view plain copy
  1. 2016 Volkswagen Beetle  
  2. 2016 Tesla Roadster  

4. 导入整个模块  import Car  

[python] view plain copy
  1. import Car  
  2.   
  3. my_beetle = car.Car('volkswagen''beetle'2016)  
  4. print(my_beetle.get_descriptive_name())  
  5.   
  6. my_tesla = car.ElectricCar('tesla''roadster'2016)  
  7. print(my_tesla.get_descriptive_name()</span>  

5.导入模块中的所有类   

     from module_name import *  

五、Python 标准库

Python标准库是一组模块,安装的Python都包含它。可使用标准库中的任何函数和类,为此只需在程序开头包含一条简单的import语句。下面来看模块collections中的一个类 ——OrderedDict

字典让你能够将信息关联起来,但它们不记录你添加键—值对的顺序要创建字典并记录其中的键—值对的添加顺序,可使用模块collections中的OrderedDictOrderedDict实例的行为几乎与字典相同,区别只在于记录了键—值对的添加顺序。

[python] view plain copy
  1. from collections import OrderedDict  
  2.   
  3. favorite_languages = OrderedDict()  
  4.   
  5. favorite_languages['jen'] = 'python'  
  6. favorite_languages['sarah'] = 'c'  
  7. favorite_languages['edward'] = 'ruby'  
  8. favorite_languages['phil'] = 'python'  
  9.   
  10. for name, language in favorite_languages.items():  
  11.     print(name.title() + "'s favorite language is " + language.title() + ".")  

注意,这里没有使用花括号,而是调用OrderedDict() 来创建一个空的有序字典,并将其存储在favorite_languages 中

[python] view plain copy
  1. Jen's favorite language is Python.  
  2. Sarah's favorite language is C.  
  3. Edward's favorite language is Ruby.  
  4. Phil's favorite language is Python.  

六、类编码风格

1.类名应采用驼峰命名法 ,即将类名中的每个单词的首字母都大写,而不使用下划线
2.实例名和模块名都采用小写格式,并在单词之间加上下划线。
3.对于每个类,都应紧跟在类定义后面包含一个文档字符串。这种文档字符串简要地描述类的功能,并遵循编写函数的文档字符串时采用的格式约定。
4.需要同时导入标准库中的模块和你编写的模块时,先编写导入标准库模块的import 语句,再添加一个空行,然后编写导入你自己编写的模块的import 语句。在包含多条import 语句的程序中,这种做法让人更容易明白程序使用的各个模块都来自何方。
阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页