8.4传递列表
使用函数挺高处理列表的效率。
1 def greet_users(names): 2 for name in names: 3 msg = "Hello,"+name.title()+"!" 4 print(msg) 5 6 names = ['guhai','huiji','kig'] 7 greet_users(names)
8.4.1在函数中修改列表
在函数中修改列表,任何修改都是永久性的。
可使用复制列表方法(切片方法)来创建副本,保留原件。
注意:不建议创建副本,因为会会降低效率。
1 def print_models(unprint_designs,complete_models): 2 while unprint_designs: 3 current_design = unprint_designs.pop() 4 print("Printing model: "+ current_design) 5 complete_models.append(current_design) 6 7 def show(complete_models): 8 print("\nThe following models have been printed: ") 9 for complete_model in complete_models: 10 print(current_model) 11 12 13 unprint_designs = ['iphone case','robot pendant','dodecahedron'] 14 complete_models = [] 15 16 print_models(unprint_designs,complete_models) 17 show(complete_models)
8.5传递任意数量的实参
在形参名之前加一个星号,使Python创建一个空元组。并将收到的所有值都封装在这个元组中。
1 def make_pizza(*toppings): 2 print("\nMaking a pizza with the following toppings: ") 3 for topping in toppings: 4 print("-"+topping) 5 6 make_pizza('pepperoni') 7 make_pizza('mushrooms','green peppers','extra cheese')
8.5.1结合使用位置实参和任意数量的实参
将接纳任意数量实参的形参放在最后。Python先匹配位置实参和关键字实参,再将余下的实参都收集到最后一个形参中。
1 def make_pizza(size,*toppings): 2 print("\nMaking a "+str(size)+"-inch pizza with the following toppings: ") 3 for topping in toppings: 4 print("-"+topping) 5 6 make_pizza(12,'pepperoni') 7 make_pizza(16,'mushrooms','green peppers','extra cheese')
8.5.2使用任意数量的关键字实参
有时候需要接受任意数量的实参,但预先不知道传递给函数的会是什么,这种情况下,可将函数编写成能够接受任意数量的键-值对。调用语句提供多少就接受多少。
1 def build_profile(first,last,**user_info): 2 profile = {} 3 profile['first_name'] = first 4 profile['last_name'] = last 5 for key,value in user_info.items(): 6 profile['key'] = value 7 return profile 8 9 user_profile = build_profile('albert','einstein',location = 'shanghai',field = 'physics') 10 print(user_profile)
8.6将函数存储在模块中
8.6.1导入整个模块
1 #第一种 2 import module_name 3 4 module_name.function_name() 5 6 #第二种 7 from module_name import funtion_name
8.6.3使用as给函数或模块指定别名
优势函数或模块名字较长或与程序现有名称冲突,可指定简短而独一无二的别名。
8.6.4导入模块中所有函数
使用星号(*)可导入Python模块中的所有函数,不需要使用句点表示法。
一般不建议导入所有函数。
8.7函数编写指南
- 函数指定描述性名称,且只在其中使用小写字母和下划线。
- 每个函数都应包含简要地阐述其功能的注释,该注释紧跟函数定义后面,并采用文档字符串格式。
- 给形参或关键字实参,等号两边不要有空格
- 代码行的长度不要超过79字符,如果超过可在函数定义中输入左括号后按回车键,并在下一行两次tab键,从而将形参列表和只缩进一层的函数体区分开。
- 如果程序或模块包含多个函数,可使用两个空格将相邻的函数分开
- 所有import语句都应放在文件开头,唯一例外是,在文件开头使用注释来描述整个程序时。
9.类
根据类来创建对象被称为实例化。
1 #创建类 2 class Dog(): 3 def _init_(self,name,age): 4 self.name = name 5 self.age = age 6 7 def sit(self): 8 print(self.name.title()+ "is now sitting") 9 10 def roll_over(self): 11 print(self.name.title() + 'rolled over')
- 类中函数称为方法
- 形参中self必不可少,还必须位于形参的前面。
- 以self为前缀的变量都可供类中的所有方法使用。
- 我们通常可以认为首字母大写的名称指的是类,而小写的名称指的是根据类创建的实例。
- 使用句号表示法调用类的属性和方法。
- 在创建多个实例的过程中,给第二个实例指定同样的名字和年龄,Python依然会根据类来创建另一个实例。
- 你可用根据需求根据一个类创建任意数量的实例,条件是将每个实例都存储在不同的变量中,或占用列表或字典的不同位置。
9.1类的属性
可以在__init__()方法中指定初始值。如果你对某个初始值这样做了,就无需包含为它提供初始值的形参。
9.2修改属性的值
1.在指定属性初始值处修改
2.通过方法修改
3.通过方法对属性的值进行递增
9.3继承
编写类时,并非总是从空白开始。
一个类继承另一个类时,总是自动获得所继承类的所有属性和方法,还可以定义自己的属性和方法。
1 class Car(): 2 def __init__(self,make,model,year): 3 self.make = make 4 self.model = model 5 self.year = year 6 self.odometer_reading = 0 7 8 def get_descriptive_name(self): 9 long_name = str(self.year) + ' '+self.make+' '+self.model 10 return long_name.title() 11 12 def read_odometer(self): 13 print("This car has "+str(self.odometer_reading)+" miles on it") 14 15 def update_odometer(self,mileage): 16 self.odometer_reading = mileage 17 18 def increament_odometer(self,mile): 19 self.odometer_reading += mile 20 21 class ElectricCar(Car): 22 """初始化父类的值""" 23 def __init__(self,make,model,year): 24 super().__init__(make,model,year)#super()特殊函数让父类和子类关联起来,父类也称为超类(superclass) 25 26 my_tesla = ElectricCar('tesla','model s',2016) 27 print(my_tesla.get_descriptive_name())
9.3.1重写父类方法
在子类中定义一个与父类同名的方法,在执行时,Python将按子类方法执行。
9.3.2将类用作属性。
在类的细节越加越多,可将类的一部分作为独立的类提取出来。将大型类拆分成协同工作的小类。
1 class Battery(): 2 def __init__(self,battery_size = 70): 3 self.battery_size = battery_size 4 5 def describe_battery(self): 6 print("This car has a "+str(self.battery_size)+'-kWh battery.') 7 8 def get_range(self): 9 if self.battery_size == 70: 10 range = 240 11 elif self.battery_size == 85: 12 range = 270 13 14 message = "This car can go approximately "+str(range) 15 message += " miles on full charge." 16 print(message) 17 18 class Car(): 19 def __init__(self,make,model,year): 20 self.make = make 21 self.model = model 22 self.year = year 23 self.odometer_reading = 0 24 25 def get_descriptive_name(self): 26 long_name = str(self.year) + ' '+self.make+' '+self.model 27 return long_name.title() 28 29 def read_odometer(self): 30 print("This car has "+str(self.odometer_reading)+" miles on it") 31 32 def update_odometer(self,mileage): 33 self.odometer_reading = mileage 34 35 def increament_odometer(self,mile): 36 self.odometer_reading += mile 37 38 class ElectricCar(Car): 39 def __init__(self,make,model,year): 40 super().__init__(make,model,year)#super()特殊函数让父类和子类关联起来,父类也称为超类(superclass) 41 self.battery = Battery() 42 43 my_tesla = ElectricCar('tesla','model s',2016) 44 print(my_tesla.get_descriptive_name()) 45 my_tesla.battery.describe_battery() 46 my_tesla.battery.get_range()
本实例将Battery()独立出来作为一个类。
9.6类编码的风格
- 类名采用驼峰命名法,即将类名中的每个单词的首字母都大写,而不使用下划线,实例名和模块名采用小写格式,并在单词之间加上下划线。
- 对于每个类,都应紧跟在类定义后面包含一个文档字符串。
- 可使用空行来组织代码,但不要滥用。在类中,可使用一个空行来分隔方法;在模块中,可使用两个空行来分隔类。
- 需要同时导入标准库中的模块和你编写的模块时,先编写导入标准库的import语句,在添加一个空行,然后导入你自己编写的模块的import语句。