1. 程式人生 > >《Python程式設計:從入門到實踐》第9章-類 習題

《Python程式設計:從入門到實踐》第9章-類 習題

文章目錄

9-1 餐館

建立一個名為Restaurant的類,其方法__init__()設定兩個屬性:restaurant_name和cuisine_type。建立一個名為describe_restaurant()的方法和一個名為open_restaurant()的方法,其中前者列印前述兩項資訊,而後者列印一條訊息,指出餐館正在營業。
根據這個類建立一個名為restaurant的例項,分別列印其兩個屬性,再呼叫前述的兩個方法。

class Restaurant():
	"""docstring for Restaurant"""
	
	def __init__(self, restaurant_name, cuisine_type):
		self.name = restaurant_name
		self.type = cuisine_type
		#self.name---變數(可以通過例項訪問的變數稱為屬性)
		#restaurant_name---形參

	def describe_restaurant(self):
		print("The restaurant's name is " + self.
name.title()) print("The restaurant has " + str(self.type) + " cuisine types.") #該方法列印了前述兩項資訊 def open_restaurant(self): print("The restaurant is open now.") #該方法列印一條訊息,指出餐館正在營業 restaurant = Restaurant('mamala', 10) print(restaurant.name.title() + ' ' + str(restaurant.type)) #列印其兩個屬性 restaurant.
describe_restaurant() restaurant.open_restaurant() #根據要求呼叫前述兩個方法。

區分變數和實參:以self為字首的變數都可供類中的所有方法使用。還可以通過類的任何例項來訪問這些變數。

self.name = restaurant_name獲取儲存在形參restaurant_name中的值,並將其儲存到變數name中,然後該變數被關聯到當前建立的例項。

像這樣可通過例項訪問的變數稱為屬性

build

Mamala 10
The restaurant's name is Mamala
The restaurant has 10 cuisine types.
The restaurant is open now.
[Finished in 2.0s]

9-2 三家餐館

根據你為完成練習9-1而編寫的類建立三個例項,並對每個例項呼叫方法describe_restaurant。

類的主體不變 增加兩個例項 程式碼如下

restaurant_a = Restaurant('mamala', 10)
restaurant_b = Restaurant("jason's library", 8)
restaurant_c = Restaurant("bread talk", 4)

restaurant_a.describe_restaurant()
restaurant_b.describe_restaurant()
restaurant_c.describe_restaurant()

build


The restaurant's name is Mamala
The restaurant has 10 cuisine types.

The restaurant's name is Jason'S Library
The restaurant has 8 cuisine types.

The restaurant's name is Bread Talk
The restaurant has 4 cuisine types.
[Finished in 0.5s]

9-3使用者

建立一個名為User的類,其中包含屬性first_name和last_name,還有使用者簡介通常會儲存的其他幾個屬性。在類User定義一個名為describe_user()的方法,它列印使用者資訊的摘要;再定義一個名為greet_user()的方法,它向用戶發出個性化的問候。
建立多個表示不同使用者的例項,並對每個例項都呼叫上述兩個方法。

class User():

	def __init__(self, first_name, last_name, age, career):
		self.f_name = first_name
		self.l_name = last_name
		self.age = age
		self.career = career

	def describe_user(self):
		print("\nThe user's name is " + self.f_name.title() + self.l_name.title() + ".")
		print("Age is " + str(self.age) + ".")
		print("The user's career is " + self.career.title() + ".")

	def greet_user(self):
		print("Hello," + self.f_name.title() + " " + self.l_name.title() + ".")

user_a = User('wang', 'xizhi', 25, 'calligrapher' )
user_b = User('Xie', 'an', 40, 'polician')
user_c = User('Xie', 'lingyun', 37, 'poet')

user_a.describe_user()
user_a.greet_user()

user_b.describe_user()
user_b.greet_user()

user_c.describe_user()
user_c.greet_user()

build


The user's name is WangXizhi.
Age is 25.
The user's career is Calligrapher.
Hello,Wang Xizhi.

The user's name is XieAn.
Age is 40.
The user's career is Polician.
Hello,Xie An.

The user's name is XieLingyun.
Age is 37.
The user's career is Poet.
Hello,Xie Lingyun.
[Finished in 0.1s]

9-4 就餐人數

(1)①

class Restaurant():
	"""docstring for Restaurant"""
	
	def __init__(self, restaurant_name, cuisine_type):
		self.name = restaurant_name
		self.type = cuisine_type
		self.number_served = 0 
		#設定該屬性的預設值為0

	def count_number(self):
		print("There were " + str(self.number_served) + " customers having meals in the restaurant.")
		#列印有多少人在這個餐館就餐過。


restaurant = Restaurant('mamala', 10)
restaurant.count_number() 

build

There were 0 customers having meals in the restaurant.
[Finished in 0.3s]


上述類主體不變,用句點表示法直接訪問並設定屬性number_served

restaurant = Restaurant('mamala', 10)
restaurant.number_served = 100
restaurant.count_number()

build

There were 100 customers having meals in the restaurant.

(2)(3)

class Restaurant():
	"""docstring for Restaurant"""
	
	def __init__(self, restaurant_name, cuisine_type):
		self.name = restaurant_name
		self.type = cuisine_type
		self.number_served = 0 
		#設定該屬性的預設值為0

	def count_number(self):
		print("There were " + str(self.number_served) + " customers having meals in the restaurant.")
		#列印有多少人在這個餐館就餐過。

	def set_number_served(self, number2):
		"""設定就餐人數的方法"""
		self.number_served = number2

	def increment_number_served(self, number3):
		"""將就餐人數遞增"""
		self.number_served += number3

restaurant = Restaurant('mamala', 10)
restaurant.set_number_served(99) 
restaurant.count_number()

restaurant.increment_number_served(20)
restaurant.count_number()

build

There were 99 customers having meals in the restaurant.
There were 119 customers having meals in the restaurant.

9-5 嘗試登入次數

class User():

	def __init__(self, first_name, last_name, age, career, login_attempts):
		self.f_name = first_name
		self.l_name = last_name
		self.age = age
		self.career = career
		self.login_attempts = login_attempts
    
    #--snip--
	def login_attempts_read(self):
		"""打印出loginattempts的讀數"""
		print(str(self.login_attempts))

	def increment_login_attempts(self, value):
		self.login_attempts += value

	def reset_login_attempts(self):
		self.login_attempts = 0

user = User("wang", "xizhi", 25, "calligrapher", 2) #建立一個例項
user.login_attempts_read()

number = 0
while number <= 5:
	user.increment_login_attempts(5)
	number += 1
	#呼叫increment_login_attempts()方法6次。

user.login_attempts_read()

user.reset_login_attempts()
user.login_attempts_read()

9-6冰淇淋小店

冰淇淋小店是一種特殊的餐館。編寫一個名為IceCreamStand的類,讓它繼承你為完成練習9-1或練習9-4而編寫的Restaurant類。這兩個版本的Restaurant類都可以,挑選你更喜歡的那個即可。新增一個名為flavors的屬性,用於儲存一個由各種口味的冰淇淋組成的列表。編寫一個顯示這些冰淇淋的方法。建立一個IceCreamStand例項,並呼叫這個方法。

使用了9-4的Restaurant的類

class Restaurant():
	"""docstring for Restaurant"""
	
	def __init__(self, restaurant_name, cuisine_type):
		self.name = restaurant_name
		self.type = cuisine_type
		self.number_served = 0 
		#設定該屬性的預設值為0
		self.flavors = ['chocolate', 'strawberry', 'milk', 'kiwifruit'] 
		#新增一個名為flavors的屬性,用於儲存一個由各種口味的冰淇淋組成的列表。

	--snip--#9-4中的程式碼
	
	def display_flavors(self):
	    """編寫一個顯示這些冰淇淋的方法"""
		message = "This IceCreamStand provides icecreams of different flavors of "
		
		num = 0
		while num < 3:
			message += self.flavors[num] + ","
			num += 1

		message += self.flavors[3] + "."
		print(message)

class IceCreamStand(Restaurant):
	"""編寫一個冰淇淋小店的類。繼承Restaurant。"""
	def __init__(self, restaurant_name, cuisine_type):
		"""初始化父類的屬性"""
		super().__init__(restaurant_name,cuisine_type)

my_icecream = IceCreamStand('Dairy Queen', 10)
my_icecream.display_flavors()

Build

This IceCreamStand provides icecreams of different flavors of chocolate,strawberry,milk,kiwifruit.

還存在的問題
flavor的屬性新增在父類中還是新增在子類中
方法編寫在父類中還是主類中
覺得自己這樣處理不是很好

9-7 管理員

管理員是一種特殊的使用者。編寫一個名為Admin的類,讓它繼承你為完成練習9-3或練習9-5而編寫的User類。新增一個privileges的屬性,用於儲存一個由字串(如"can add post"、 “can delete post”、 "can ban user"等)組成的列表。編寫一個名為show_privileges()的方法,它顯示管理員的許可權。建立一個Admin例項,並呼叫這種方法。

class User():

	def __init__(self, first_name, last_name, age, career, login_attempts):
		self.f_name = first_name
		self.l_name = last_name
		self.age = age
		self.career = career
		self.login_attempts = login_attempts
    
	--snip--#Above借用9-3 User的語句。不影響下面的內容。

class Admin(User):

	def __init__(self, first_name, last_name, age, career, login_attempts):
		"""初始化父類的屬性"""
		super().__init__(first_name, last_name, age, career, login_attempts)
		self.privileges = ["can add post", "can delete post", "can ban user"]
		#添加了一個新的屬性

	def show_privileges(self):
		"""顯示管理員的許可權"""
		num = 0
		while num < 3:
			message = "Admin " + self.privileges[num] + "."
			num += 1
			print(message)

admin = Admin("wang", "xizhi", 25, "calligrapher", 2) #建立Admin的例項
admin.show_privileges() #呼叫方法

build

Admin can add post.
Admin can delete post.
Admin can ban user.

9-8 許可權

編寫一個名為Privileges的類,它只有一個屬性——privileges,其中儲存了練習9-7所說的字串列表。將方法show_privileges()移到這個類中。在Admin類中,將一個Privileges例項用作其屬性。建立一個Admin例項,並使用方法show_privileges()來顯示其許可權。

class User():

	def __init__(self, first_name, last_name, age, career, login_attempts):
		self.f_name = first_name
		self.l_name = last_name
		self.age = age
		self.career = career
		self.login_attempts = login_attempts
    
	--snip--
	
class Privileges():

	def __init__(self, privileges = ["can add post", "can delete post", "can ban user"]):
		self.privileges = privileges
		#新增屬性

	def show_privileges(self):
		"""顯示管理員的許可權"""
		num = 0
		while num < 3:
			message = "Admin " + self.privileges[num] + "."
			num += 1
			print(message)

class Admin(User):

	def __init__(self, first_name, last_name, age, career, login_attempts):
		"""初始化父類的屬性"""
		super().__init__(first_name, last_name, age, career, login_attempts)
		self.privilege = Privileges()
	

admin = Admin("wang", "xizhi", 25, "calligrapher", 2) #建立Admin的例項
admin.privilege.show_privileges() #呼叫方法

剛開始的時候出現了錯誤。
錯誤如下

##line50&47出現的問題
TypeError: __init__() missing 1 required positional argument: 'privileges'

原code為
沒有將形參與屬性privileges關聯起來
正確的code為
變數是self.privileges,該變數(屬性)關聯到當前建立的例項。具體見p139,這點要好好理解。
變數是self.privileges,該變數(屬性)關聯到當前建立的例項。具體見p139,這點要好好理解。

build

Admin can add post.
Admin can delete post.
Admin can ban user.

9-9 電瓶升級

在本節最後一個electric_car.py版本中,給Battery類新增一個名為upgrade_battery()的方法。這個方法檢查電瓶容量,如果它不是85,就將它設定為85。建立一輛電瓶容量為預設值的電動汽車,呼叫方法get_range(),然後對電瓶進行升級,並再次呼叫get_range()。你會看到這輛車的續航里程增加了。

class Car():
	"""一次模擬汽車的簡單嘗試"""

	def __init__(self, make, model, year):
		"""初始化描述汽車的屬性"""
		self.make = make
		self.model = model
		self.year = year
		self.odometer_reading = 0
		#名為odomerter_reading的屬性
		#在方法 __init__()內指定初始值,無需包含為它提供初始值的形參。

	def get_descriptive_name(self):
		"""返回整潔的描述性資訊"""
		long_name = str(self.year) + ' ' + self.make + ' ' + self.model
		return long_name.title()
	
	--snip--#省去無用資訊

#將例項用作屬性
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)

	def upgrade_battery(self):
		"""檢查電瓶容量並設定"""
		if self.battery_size != 85:
			self.battery_size = 85 
			#注意這裡賦值的物件
			#一定要區分self.battery_size和battery_size

class ElectricCar(Car):
	"""Represent aspects of a car, specific to electric vehicles."""

	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())
my_tesla.battery.describe_battery()
my_tesla.battery.upgrade_battery()
my_tesla.battery.get_range()

build

2016 Tesla Model S
This car has a 70-kwh battery.
This car can go approximately 270 miles on a full charge.

注意區分self.battery_size和battery_size

9-10 匯入Restaurant類

將最新的Restaurant類儲存在一個模組中。在另一個檔案中,匯入Restaurant類,建立一個Restaurant例項,並呼叫Restaurant的一個方法,以確認import語句正確無誤。

建立模組 restaurant.py 將Restaurant類儲存在該模組中。
import語句如下。from 檔案(模組)名 import 類名

from restaurant import Restaurant

restaurant = Restaurant('mamala', 10)  
#建立Restaurant類例項。
restaurant.set_number_served(99) 
restaurant.count_number()

restaurant.increment_number_served(20)
restaurant.count_number()

【只要注意import語句無誤即沒有大問題】

9-11 匯入Admin類(這題要注意一下)

以為完成練習9-8而做的工作為基礎,將User、Privileges和Admin類儲存在一個模組中,再建立一個檔案,在其中建立一個Admin例項並對其呼叫方法show_privileges(),以確認一切都能正確地執行。

建立模組,儲存User、Privileges和Admin類
建立Admin例項

from user import Admin
#匯入Admin類

admin = Admin("wang", "xizhi", 25, "calligrapher", 2)
admin.privilege.show_privileges()

build

Admin can add post.
Admin can delete post.
Admin can ban user.

9-12 多個模組

將User類儲存在一個模組中,並將Privileges和Admin類儲存在另一個模組中。再建立一個檔案,在其中建立一個Admin例項,並對其呼叫方法show_privileges(),以確認一切都依然能夠正確地執行。

(1)模組1 users.py

class User():

	def __init__(self, first_name, last_name, age, career, login_attempts):
		self.f_name = first_name
		self.l_name = last_name
		self.age = age
		self.career = career
		self.login_attempts = login_attempts
    
	def describe_user(self):
		print("\nThe user's name is " + self.f_name.title() + self.l_name.title() + ".")
		print("Age is " + str(self.age) + ".")
		print("The user's career is " + self.career.title() + ".")

	def gre