python自学之《Python编程:从入门到实践》——关于类和读取文件

第 9 章类

(1)面向对象编程 是最有效的软件编写方法之一。在面向对象编程中,你编写表示现实世界中的事物和情景的类,并基于这些类来创建对象。编写类时,你定义一大类对象都有的通用行为。基于类创建对象 时,每个对象都自动具备这种通用行为,然后可根据需要赋予每个对象独特的个性。使用面向对象编程可模拟现实情景,其逼真
程度达到了令你惊讶的地步。
(2)根据类来创建对象被称为实例化 ,这让你能够使用类的实例。在本章中,你将编写一些类并创建其实例。你将指定可在实例中存储什么信息,定义可对这些实例执行哪些操作。你还将编写一些类来扩展既有类的功能,让相似的类能够高效地共享代码。你将把自己编写的类存储在模块中,并在自己的程序文件中导入其他程序员编写的类。
(3)理解面向对象编程有助于你像程序员那样看世界,还可以帮助你真正明白自己编写的代码:不仅是各行代码的作用,还有代码背后更宏大的概念。了解类背后的概念可培养逻辑思维,让你能够通过编写程序来解决遇到的几乎任何问题。随着面临的挑战日益严峻,类还能让你以及与你合作的其他程序员的生活更轻松。如果你与其他程序员基于同样的逻辑来编写代码,你们就能明白对方所做的工作;你编写的程序将能被众多合作者所理解,每个人都能事半功倍。
在这里插入图片描述

>>> class Dog():
...     def __init__(self,name,age):
...         self.name = name
...         self.age = age
...     def sit(self):
...         print(self.name.title() + " is now sitting.")
...     def roll_over(self):
...         print(self.name.title() + " rolled over!")
... 
>>> 

在这里插入图片描述

>>> class Dog():
...     def __init__(self,name,age):
...         self.name = name
...         self.age = age
...     def sit(self):
...         print(self.name.title() + " is now sitting.")
...     def roll_over(self):
...         print(self.name.title() + " rolled over!")
... 
>>> my_dog = Dog('willie', 6)
>>> print("My dog's name is " + my_dog.name.title() + ".")
My dog's name is Willie.
>>> print("My dog is " + str(my_dog.age) + " years old.")
My dog is 6 years old.
>>> 

这里使用的是前一个示例中编写的 Dog 类。在❶处,我们让 Python 创建一条名字为 ‘willie’ 、年龄为 6 的小狗。遇到这行代码时, Python 使用实参 ‘willie’ 和 6 调用 Dog 类中的方法 init() 。方法 init() 创建一个表示特定小狗的示例,并使用我们提供的值来设置属性 name 和 age 。方法 init() 并未显式地包含 return 语句,但 Python 自动返回一个表示这条小狗的实例。我们将这个实例存储在变量 my_dog 中。在这里,命名约定很有用:我们通常可以认为首字母大写的名称(如 Dog )指的是类,而小写的名称(如 my_dog )指的是根据类创建的实例。
在这里插入图片描述
在这里插入图片描述


>>> my_dog = Dog('willie',6)
>>> my_dog.sit()
Willie is now sitting.
>>> my_dog.roll_over()
Willie rolled over!
>>> 

在这里插入图片描述在这里插入图片描述

9.2 使用类和实例
你可以使用类来模拟现实世界中的很多情景。类编写好后,你的大部分时间都将花在使用根据类创建的实例上。你需要执行的一个重要任务是修改实例的属性。你可以直接修改实例的属性,也可以编写方法以特定的方式进行修改。
9.2.1 Car 类
下面来编写一个表示汽车的类,它存储了有关汽车的信息,还有一个汇总这些信息的方法:

>>> class Car():
...     def __init__(self, make, model, year):
...         self.make = make
...         self.model = model
...         self.year = year
...     def get_descriptive_name(self):
...         long_name = str(self.year) + ' ' + self.name + ' ' + self.model
...         return long_name.title()
... 
>>> my_new_car = Car('audi', 'a4', 2016)
>>> print(my_new_car.get_descriptive_name())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 7, in get_descriptive_name
AttributeError: 'Car' object has no attribute 'name'
>>> class Car():
...     def __init__(self, make, model, year):
...         self.make = make
...         self.model = model
...         self.year = year
...     def get_descriptive_name(self):
...         long_name = str(self.year) + ' ' + self.make + ' ' + self.model
...         return long_name.title()
... 
>>> my_new_car = Car('audi', 'a4', 2016)
>>> print(my_new_car.get_descriptive_name())
2016 Audi A4
>>> 

在这里插入图片描述在这里插入图片描述


>>> 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):
...         pass
...     def read_odometer(self):
...         print("This car has " + str(self.odometer_reading) + " miles on it.")
... 
>>> my_new_car = Car('audi', 'a4', '2016')
>>> print(my_new_car.get_descriptive_name())
None
>>> my_new_car.read_odometer()
This car has 0 miles on it.
>>> 

9.2.3 修改属性的值
可以以三种不同的方式修改属性的值:直接通过实例进行修改;通过方法进行设置;通过方法进行递增(增加特定的值)。下面依次介绍这些方法。
(1)直接修改属性的值要修改属性的值,最简单的方式是通过实例直接访问它。下面的代码直接将里程表读数设置为 23 :

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

9.3 继承
(1)编写类时,并非总是要从空白开始。如果你要编写的类是另一个现成类的特殊版本,可使用继承 。一个类继承 另一个类时,它将自动获得另一个类的所有属性和方法;原有的类称为父类 ,而新类称为子类 。子类继承了其父类的所有属性和方法,同时还可以定义自己的属性和方法。
9.3.1 子类的方法 init()
(2)创建子类的实例时, Python 首先需要完成的任务是给父类的所有属性赋值。为此,子类的方法 init() 需要父类施以援手。
(3)例如,下面来模拟电动汽车。电动汽车是一种特殊的汽车,因此我们可以在前面创建的 Car 类的基础上创建新类 ElectricCar ,这样我们就只需为电动汽车特有的属性和行为编写代码。下面来创建一个简单的 ElectricCar 类版本,它具备 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 = str(self.year) + ' ' + self.name + ' ' + self.model
...         return long_name.title()
...     def read_odometer(self):
...         print("This car has " + str(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)
... 
>>> my_tesla = ElectricCar('tesla', 'model s', 2016 )
>>> print(my_tesla.get_descriptive_name())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 8, in get_descriptive_name
AttributeError: 'ElectricCar' object has no attribute 'name'
>>> print(my_tesla.get_descriptive_name())
KeyboardInterrupt
>>> 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 = str(self.year) + ' ' + self.make + ' ' + self.model
...         return long_name.title()
...     def read_odometer(self):
...         print("This car has " + str(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)
... 
>>> my_tesla = ElectricCar('tesla', 'model s', 2016 )
>>> print(my_tesla.get_descriptive_name())
2016 Tesla Model S
>>> 

在这里插入图片描述

9.3.3 给子类定义属性和方法
让一个类继承另一个类后,可添加区分子类和父类所需的新属性和方法。
下面来添加一个电动汽车特有的属性(电瓶),以及一个描述该属性的方法。我们将存储电瓶容量,并编写一个打印电瓶描述的方法:

在这里插入图片描述

>>> class ElectricCar(Car):
...     def __init__(self, make, model, year):
...         super().__init__(make, model, year)
...         self.battery_size = 70
...     def describe_battery(self):
...         print("This car has a " + str(self.battery_size) + "-kWh battery.")
... 
>>> my_tesla = ElectricCar('tesla', 'model s', 2016)
>>> print(my_tesla.get_descriptive_name())
2016 Tesla Model S
>>> my_tesla.describe_battery()
This car has a 70-kWh battery.
>>> 

在这里插入图片描述在这里插入图片描述
在这里插入图片描述

>>> class Battery():
...     def __init__(self, battery_size=70):
...         self.battery_size =battery_size
...     def describe_battery(self):
...         print("This car has a " + str(self.battery_size) + "-kWh battery.")
... 
>>> class ElectricCar(Car):
...     def __init__(self, make, model, year):
...         super().__init__(make, model, year)
...         self.battery = Battery()
... 
>>> my_tesla = ElectricCar('tesla', 'model s', 2016)
>>> print(my_tesla.get_descriptive_name())
2016 Tesla Model S
>>> my_tesla.battery.describe_battery()
This car has a 70-kWh battery.
>>> 

在这里插入图片描述


>>> class Battery():
...     def __init__(self, battery_size = 70):
...         self.battery_size = battery_size
...     def describe_battery(self):
...         print("This car has a " + str(self.battery_size) + "-kWh battery.")
...     def get_range(self):
...         if self.battery_size = 70:
  File "<stdin>", line 7
    if self.battery_size = 70:
                         ^
SyntaxError: invalid syntax
>>> class Battery():
...     def __init__(self, battery_size=70):
...         self.battery_size = battery_size
...     def describe_battery(self):
...         print("This car has a " + str(self.battery_size) + "-kWh battery.")
...     def get_range(self):
...         if self.battery_size == 70:
...             range = 240
...         elif self.battery_size ==85:
...             range = 270
...         message = "This car can go approximately " + str(range)
...         message += " miles on a full charge."
...         print(message)
... 
>>> my_tesla = ElectricCar('tesla', 'model s', 2016)
>>> print(my_tesla.get_descriptive_name())
2016 Tesla Model S
>>> my_tesla.battery.describe_battery()
This car has a 70-kWh battery.
>>> my_tesla.battery.get_range()
This car can go approximately 240 miles on a full charge.
>>> 

在这里插入图片描述

9.4 导入类
随着你不断地给类添加功能,文件可能变得很长,即便你妥善地使用了继承亦如此。为遵循 Python 的总体理念,应让文件尽可能整洁。为在这方面提供帮助, Python 允许你将类存储在模块中,然后在主程序中导入所需的模块。
9.4.1 导入单个类
下面来创建一个只包含 Car 类的模块。这让我们面临一个微妙的命名问题:在本章中,已经有一个名为 car.py 的文件,但这个模块也应命名为 car.py ,因为它包含表示汽车的代码。我们将这样解决这个命名问题:将 Car 类存储在一个名为 car.py 的模块中,该模块将覆盖前面使用的文件 car.py 。从现在开始,使用该模块的程序都必须使用更具体的文件名,如 my_car.py 。下面是模块 car.py ,其中只包含 Car 类的代码:

在这里插入图片描述

>>> from car import car
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: cannot import name 'car' from 'car' (/home/yhm/Downloads/car.py)
>>> from car import Car
>>> my_new_car = Car('audi', 'a4', 2016)
>>> print(my_new_car.get_descriptive_name())
2016 Audi A4
>>> my_new_car.odometer_reading=23
>>> my_new_car.read_odometer()
This car has 23 miles on it.
>>> 

9.4.2 在一个模块中存储多个类
虽然同一个模块中的类之间应存在某种相关性,但可根据需要在一个模块中存储任意数量的类。类 Battery 和 ElectricCar 都可帮助模拟汽车,因此下面将它们都加入模块car.py 中:
在这里插入图片描述

在这里插入图片描述

>>> from car import ElecreicCar
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: cannot import name 'ElecreicCar' from 'car' (/home/yhm/Downloads/car.py)
>>> 

在这里插入图片描述在这里插入图片描述没看懂标黄的那句话

>>> import car
>>> my_beetle = car.Car('volkswagen', 'beetle', 2016)
>>> print(my_beetle.get_descriptive_name())
2016 Volkswagen Beetle
>>> my_tesla = car.ElectricCar('tesla', 'roadster', 2016)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'car' has no attribute 'ElectricCar'
>>> 

在这里插入图片描述在这里插入图片描述

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

在这里插入图片描述

>>> from collections import OrderedDict
>>> favorite_languages = OderedDict()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'OderedDict' is not defined
>>> favorite_languages = OrderedDict()
>>> favorite_languages['jen'] = 'python'
>>> favorite_languages['sarah'] = 'c'
>>> favorite_languages['edward'] = 'ruby'
>>> favorite_languages['phil'] = 'python'
>>> for name, language in favorite_languages.items():
...     print(name.title() + "'s favorite language is " +
...         language.title() + ".")
... 
Jen's favorite language is Python.
Sarah's favorite language is C.
Edward's favorite language is Ruby.
Phil's favorite language is Python.
>>> 

在这里插入图片描述在这里插入图片描述在这里插入图片描述

>>> with open('pi_digits.txt') as file_object:
...     contents = file_object.read()
...     print(contents)
... 
3.1415926535
8979323846
2643383279

>>> with open('pi_digits.txt') as file_object:
...     contents = file_object.read()
...     print(contents.rstrip())
... 
3.1415926535
8979323846
2643383279
>>> 

在这里插入图片描述在这里插入图片描述
在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

>>> import json
>>> numbers = [2, 3, 5, 7, 11, 13]
>>> filename = 'number.json'
>>> filename = 'numbers.json'
>>> with open(filename, 'w') as f_obj:
...     json.dump(numbers, f_obj)
... 
>>> 
>>> with open(filename) as f_obj:
...     numbers = json.load(f_obj)
... 
>>> print(numbers)
[2, 3, 5, 7, 11, 13]
>>> 

在这里插入图片描述

>>> username = input("What is your name?")
What is your name?Eric
>>> filename = 'username.json'
>>> with open(filename, 'w') as f_obj:
...     json.dump(username, f_obj)
...     print("We'll remember you when you come back, " + username + "!")
... 
We'll remember you when you come back, Eric!
>>> with open(filename) as f_obj:
...     username = json.load(f_obj)
...     print("Welcome back, " + username + "!")
... 
Welcome back, Eric!
>>> try:
...     with open(filename) as f_obj:
...         username = json.load(f_obj)
... except FileNotFoundError:
...     username = input("What is your name? ")
...     with open(filename, 'w') as f_obj:
...         json.dump(username, f_obj)
...         print("We'll remember you when you come back, " + username + "!")
... else:
...     print("Welcome back, " + username + "!")
... 
Welcome back, Eric!
>>> 

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值