Python-基础入门-学习笔记(5):函数和类

Python-基础入门-学习笔记(5):函数和类

一、函数

函数是带名字的代码块,用于完成具体的工作。

1、定义函数

def greet_user():  #定义函数
·······
greet_user()  #调用函数

在冒号之后的所有缩进行构成了函数体。
(1)向函数传递信息
将需要传递的值写在括号内,即可。

def greet_user(username):  #其中username接受我们指定的任意值 

(2)实参和形参
变量username相当于形参,即函数完成其工作所需的一项信息;而值’jesse’相当于实参,即用户想要赋的值。
传递时,是将实参赋给形参

练习
在这里插入图片描述
2、传递实参
函数定义中可能包含多个形参,因此函数调用中也可能包含多个实参。
(1)位置实参
关联方式是基于实参的顺序。

def describe_pet(animal_type, pet_name):
	······
describe_pet('hamster','harry')

位置实参的顺序千万不能反
(2)关键字实参
关键字实参是传递给函数的名称-值对。

def describe_pet(animal_type, pet_name):
	······
describe_pet(animal_type='hamster', pet_name='harry')

这样的做法可以避免对应错误问题
(3)默认值
给形参指定默认值后,可在函数调用中省略相应的实参。

# 将动物类型默认为
def describe_pet(animal_type='dog', pet_name):
	······
describe_pet(pet_name='harry')

如果显示地给animal_type赋值的话,将会覆盖掉默认值

练习
在这里插入图片描述
3、返回值
函数返回的值被称为返回值,在函数中,可使用return语句将值返回到调用函数的代码行。

def get_formatted_name(first_name,last_name):
	"""返回整洁的姓名"""
	full_name = first_name + ' ' + last_name
	return full_name.title()

musician = get_formatted_name('jimi','hendrix')
print(musician)

上述代码将full_name的值转换为首字母大写,并将结果返回到函数调用行。
调用返回值的函数时,需要提供一个变量,用于存储返回的值。

函数可返回任何类型的值,包括列表和字典等较复杂的数据结构。

练习
在这里插入图片描述
4、传递函数
(1)将列表传递给函数后,函数就能直接访问其内容。

def greet_users(names):
	for name in names:
		msg = "Hello, " + name.title() + "!"
		print(msg)
usernames = ['hannah','ty','margot']
#将列表传递给函数
greet_users(usernames)

(2)将列表传递给函数后,函数就可对其进行修改,这个修改是永久性的。
类似于C语言中封装某个函数(.c和.h文件),并在main函数中进行调用,调用时执行该函数,并将返回值重新赋给主函数。这有助于将复杂的任务划分成一系列的步骤,并且调用灵活。

(3)如果要禁止函数修改列表,可向函数传递列表的副本而不是原件;这样函数所做的任何修改都只影响副本,而丝毫不影响原件。

#切片表示法[:]创建列表的副本,函数所做的修改不会影响到列表本身。
function_name(list_name[:])

如果没有特殊要求,尽量使用原始版本,因为会避免花时间和内存创建副本,从而提高效率。

练习
在这里插入图片描述
5、传递任意数量的实参

def make_pizza(*toppings):
	"""打印顾客点的所有配料"""
	print(toppings)

make_pizza('a','b','c')

形参名*topping中的星号让Python创建一个名为toppings的空元组,并将收到的所有值都封装到这个元组中。
不论收到的实参是多少个,都适用。

(1)当结合位置实参时,需要将位置实参放在前面,将任意数量的实参放到后面。

def make_pizza(size,*toppings):

(2)有时候使用任意数量的实参,可将函数编写成能够接受任意数量的键-值对。

def build_profile(first,last,**user_info)

形参**user_info中的两个星号让Python创建一个名为user_info的空字典。

练习
在这里插入图片描述
6、将函数存储在模块中
将函数存储在被称为模块的独立文件中,再将模块导入到主程序中。
(1)导入整个模块
首先先将要封装的函数存储在一个单独的文件中,例如pizza.py,接下来我们在pizza.py目录下创建另一个名为making_pizza.py的文件,再进行调用。

import pizza   #调用pizza.py文件

pizza.make_pizza(16,'pepperoni')  #指定导入模块名称和函数名,用点隔开

代码import让Python打开文件 pizza.py,并将其中的所有函数都赋值到这个程序中,但是看不到代码。
(2)导入特定的函数

from module_name import function_name

导入module_name中的特定函数function_name

from module_name import function_0,function_1,function_2

导入module_name中的某三个函数
使用这种方法时,不用在下方进行(模块.函数名)的操作。
(3)使用as给函数指定别名

from pizza import make_pizza as mp

类似于给函数起个外号,从模块pizza中取函数make_pizza函数,并给它取名为mp。
在接下来调用时,则调用函数mp即可,通常是函数名的前几个字母的缩写。
(4)使用as给模块指定别名

import pizza as p
p.make_pizza(16,'pepperoni')

(5)导入模块中的所有函数

from pizza import *

这种方法可将pizza模块中的每个函数都复制到这个程序文件中。
最佳做法是,要么只导入你需要使用的函数,要么导入整个模块并使用句点表示法。

练习
(1)首先创建一个包括所调用函数的模块。
在这里插入图片描述
(2)之后将子模块和主模块放在同一个文件夹下。
在这里插入图片描述
(3)在主模块中调用子模块。
在这里插入图片描述
在这里插入图片描述
结果证明,均能实现!

二、类

1、创建和使用类
基于类创建对象时,每个对象都自动具备这种通用行为,然后可根据需要赋予每个对象独特的个性。类是一个整体,表示的不是某个事物,而是这个事物的任意事物。
例如创建一个小狗的类,它表示的不是一个小狗,而是任意小狗:

class Dog():     #首字母大写的名称为类
	"""一次模拟小狗的简单尝试"""
	#每当根据Dog类创建新实例时,都会自动运行
	def __init__(self,name,age):     	#self是一个指向实例本身的引用,让实例能够访问类中的属性和方法。
		"""初始化属性name和age"""
		self.name = name    #获取存储在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!")

类中的函数_init_ 称为方法,与函数的唯一差别就是调用方式不同,通过前后添加下划线的方法,避免Python默认方法与普通方法发生名称冲突。

如果运行后出现错误:take no arguments。那么请检查init左右两个有几个下划线,正确的为左右各两个!!!!!!

命名规则:首字母大写的名称指的是类,小写的名称指的是根据类创建的实例。
(1)访问属性:可使用句点表示法。

my_dog.name

(2)调用方法:在根据类创建完实例之后,就可以使用类中的语句进行控制了。

class Dog():
	--snip--

my_dog = Dog('willie',6)
my_dog.sit()   #让XX打滚(其中XX是你定义好的小狗的名字)

我们还可以同时创建多个实例,同时执行,例如你还可以添加这么一行代码:

your_dog = Dog('lucy',3)

同样会执行上述命令,只不过名字和年龄发生了改变。

练习
在这里插入图片描述
在这里插入图片描述
2、使用类和实例
实例的属性可以直接修改,也可以编写方法以特定的方式进行修改。
(1)给属性指定默认值

class Car():
	def __init__(self,make,model,year):
		"""初始化描述汽车的属性"""
		self.make = make
		self.model = model
		self.year = year
		self.odometer_reading = 0   #给属性赋初值为0

	def get_descriptive_name(self):
		--snip--
	
	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())
my_new_car.read_odometer()	 

可以在方法__init__中规定属性初值。
(2)修改属性的值
方法一:直接修改属性的值

my_new_car.odometer_reading = 23
my_new_car.read_odometer()

方法二:通过方法修改属性的值

class Car():
	--snip--

	def update_odometer(self,mileage):
		"""将里程表读数设置为指定的数"""
		self.odometer_reading = mileage

my_new_car.update_odometer(23)

通过添加一个专门用来修改属性的方法来进行修改。

方法三:通过方法对属性的值进行递增

......
def increment_odometer(self,miles):
	"""将里程表读数增加指定的量"""
	self.odometer_reading += miles

这样可以保证不是给属性赋一个全新的值,而是在原有的基础上进行改变。

练习

#设置和修改属性的默认值
class Restaurant():
	"""创建一个餐馆的类"""
	def __init__(self,restaurant_name,cuisine_type):
		"""初始化属性"""
		self.name = restaurant_name
		self.type = cuisine_type
		#添加一个属性并赋初值
		self.number_served = 0
	def describe_restaurant(self):
		"""打印餐馆信息"""
		print("The restaurant " + self.name.title() + " is " + self.type.title())
		
	def open_restaurant(self):
		"""打印餐馆营业信息"""
		print("The restaurant " + self.name.title() + " is now opening!")
	
	def read_number(self):
		"""打印就餐人数"""	
		print("The restaurant has " + str(self.number_served) + " people.")
	
	def set_number_served(self,number):
		"""修改属性的值"""
		self.number_served = number
	
	def increment_number_served(self,number):
		"""将人数增加指定的人"""
		self.number_served += number
		
#属性赋初值
my_restaurant = Restaurant('KFC','fast food')

#调用方法
my_restaurant.describe_restaurant()
my_restaurant.open_restaurant()

#方法一:直接修改属性的值
my_restaurant.number_served = 1
my_restaurant.read_number()
#方法二:通过方法修改属性的值
my_restaurant.set_number_served(2)
my_restaurant.read_number()
#方法三:通过方法对属性的值进行递增
my_restaurant.increment_number_served(1)
my_restaurant.read_number()

在这里插入图片描述

class User():
	"""创建一个用户的类"""
	def __init__(self,first_name,last_name,age,country):
		"""初始化属性"""
		self.name = first_name + last_name
		self.age = age
		self.country = country
		self.login_attempts = 0
	def describe_user(self):
		"""打印用户信息"""
		print("The user " + self.name.title() + " is " + str(self.age) +
		 " years old,and live in " + self.country.title()
		 )
		
	def greet_user(self):
		"""打印欢迎信息"""
		print("\nHello! " + self.name.title())
	
	def increment_login_attempts(self):
		"""将属性的值加1"""
		self.login_attempts += 1
		
	def reset_login_attempts(self):
		"""将属性的值归零"""
		self.login_attempts = 0
	def printing_attempts(self):
		"""打印属性的值"""
		print(self.login_attempts)
my_user = User('Bill ','Gates',24,'china')

my_user.describe_user()
my_user.greet_user()		 
my_user.printing_attempts()  #打印为0
my_user.increment_login_attempts()  #0+1=1
my_user.increment_login_attempts()	#1+1=2
my_user.increment_login_attempts()	#2+1=3
my_user.printing_attempts()	 #打印为3
my_user.reset_login_attempts()		#清零
my_user.printing_attempts()	 #打印为0

在这里插入图片描述
3、继承
编写类时,并非要从空白开始,如果是另一个现成类的特殊版本,可使用继承。一个类继承另一个类,将自动获得另一个类的所有属性和方法;原有的类成为父类,新类成为子类

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 incremeter_odometer(self,miles):
		self.odometer_reading +=miles

class ElectricCar(Car):
	"""电动车的独特之处"""

	def __init__(self,make,model,year)
		"""初始化父类属性"""
		super().__init__(make,model,year)  #super函数帮助Python将父类和子类关联起来。

my_tesla = ElectricCar('tesla','model s',2016)
print(my_tesla.get_descriptive_name())

创建子类时,父类必须包含在当前文件夹中,且位于子类前面。
(1)给子类定义属性和方法

#前面相同
.........
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.")

......#之后再调用即可

我们将新添加的属性写到了class ElectricCar(Car)中,即写到了子类中,所以父类不具备该属性。如果要想使父类和子类同时具有某属性,那么将属性添加到父类中即可。
(2)重写父类的方法
可在子类中定义一个方法与父类中的方法同名,那么可以将父类方法重写。

练习

#继承之给子类添加属性
class Restaurant():
	"""创建一个餐馆的类"""
	def __init__(self,restaurant_name,cuisine_type):
		"""初始化属性"""
		self.name = restaurant_name
		self.type = cuisine_type
	def describe_restaurant(self):
		"""打印餐馆信息"""
		print("The restaurant " + self.name.title() + " is " + self.type.title())
		
	def open_restaurant(self):
		"""打印餐馆营业信息"""
		print("The restaurant " + self.name.title() + " is now opening!")

#父类为Restaurant,子类为IceCreamStand
class IceCreamStand(Restaurant):
	"""冰激凌小店的独特之处"""
	def __init__(self,restaurant_name,cuisine_type,flavors):
		"""初始化父类属性"""
		super().__init__(restaurant_name,cuisine_type)
		self.flavors = flavors
	def describe_flavors(self):
		"""打印冰激凌的风味"""
		print("The icecream's flavor is " + self.flavors)
		
#属性赋初值
my_restaurant = IceCreamStand('KFC','fast food','strawberry')

#调用方法
my_restaurant.describe_restaurant()
my_restaurant.open_restaurant()
#创建实例并调用它
my_restaurant.describe_flavors()

在这里插入图片描述

#继承之创建实例并调用
class User():
	"""创建一个用户的类"""
	def __init__(self,first_name,last_name,age,country):
		"""初始化属性"""
		self.name = first_name + last_name
		self.age = age
		self.country = country	
	def describe_user(self):
		"""打印用户信息"""
		print("The user " + self.name.title() + " is " + str(self.age) +
		 " years old,and live in " + self.country.title()
		 )		
	def greet_user(self):
		"""打印欢迎信息"""
		print("Hello! " + self.name.title())
#父类为User,子类为Admin
class Admin(User):	
	def __init__(self,first_name,last_name,age,country,privileges):
		super().__init__(first_name,last_name,age,country)
		self.privileges = privileges
		
	def show_privileges(self):
		print("\nYou can "+ self.privileges)
#创建实例		
my_user = Admin('Bill ','Gates',24,'china','add post')
#调用方法
my_user.describe_user()
my_user.greet_user()		
my_user.show_privileges()
#继承之实例用作属性
class User():
	"""创建一个用户的类"""
	def __init__(self,first_name,last_name,age,country):
		"""初始化属性"""
		self.name = first_name + last_name
		self.age = age
		self.country = country	
		
	def describe_user(self):
		"""打印用户信息"""
		print("The user " + self.name.title() + " is " + str(self.age) +
		 " years old,and live in " + self.country.title() + "."
		 )		
		 
	def greet_user(self):
		"""打印欢迎信息"""
		print("Hello! " + self.name.title() + ".")

class Privileges():
	"""编写一个只有特权属性的类"""
	def __init__(self,privileges='add post'):
		self.privileges = privileges
	
	def show_privileges(self):
		print("\nYou can " + self.privileges)
		
#父类为User,子类为Admin
class Admin(User):	
	def __init__(self,first_name,last_name,age,country):
		super().__init__(first_name,last_name,age,country)
		self.privileges = Privileges()
		
#创建实例		
my_user = Admin('Bill ','Gates',24,'china')
#调用方法
my_user.describe_user()
my_user.greet_user()		
my_user.privileges.show_privileges()

在这里插入图片描述
4、导入类
(1)导入单个类
假设我们创建了一个Car类,并保存在模块car.py中,在导入该类时我们可以这样写:

form car import Car   #从模块car中导入类Car

导入之后就相当于Car类是这个文件中定义的一样,所以Car类中所包含的方法可以直接使用。
(2)在一个模块中存储多个类
如果在car.py中存储多个类,如下所示:

class Car():
	--snip--
class Battery():
	--snip--
class ElectricCar(Car):
	--snip--

我们要是想导入某一个类,可以这样做:

from car import ElectricCar
........

(3)从一个模块中导入多个类

from car import Car,ElectricCar  #导入了Car和ElectricCar这两个类
......

(4)导入整个模块

import car #导入整个car模块
......
#在使用时记得用'.'号访问类
my_bettle = car.Car('volkswagen','bettle',2016)
my_tesla = car.ElectricCar('tesla','roadster',2016)

(5)导入模块中的所有类

from cao import * #导入整个car模块
......

尽量不使用导入模块中所有类的方法,因为不清晰,容易引发错误。
(6)在一个模块中导入另一个模块
如果发现一个模块中的类依赖于另一个模块中的类,可在前一个模块中中导入必要的类。

假设子类Battery和ElectricCar需要用到父类Car,那么我们必须要先从Car模块中调用Car父类,才可以正常使用。

一般先尽可能在一个文件中完成所有的工作,确定一切都能正常运行后,再将类移到独立的模块中。

练习
(1)导入单个类
首先建立一个单独的模块,只存储一个类
restaurant.py

"""一组用于描述餐厅信息的类"""

class Restaurant():
	"""创建一个餐馆的类"""
	def __init__(self,restaurant_name,cuisine_type):
		"""初始化属性"""
		self.name = restaurant_name
		self.type = cuisine_type
	def describe_restaurant(self):
		"""打印餐馆信息"""
		print("The restaurant " + self.name.title() + " is " + self.type.title())
		
	def open_restaurant(self):
		"""打印餐馆营业信息"""
		print("The restaurant " + self.name.title() + " is now opening!")

导入该模块中的类,并创建restaurant实例

from restaurant import Restaurant

my_restaurant = Restaurant('KFC','fast food')

my_restaurant.describe_restaurant()
my_restaurant.open_restaurant()

在这里插入图片描述
我们可以发现能正常执行!

(2)在一个模块中存储多个类
建立一个模块,里面存储了多个类
admin.py

"""一组用于表示用户信息的类"""

class User():
	"""创建一个用户的类"""
	def __init__(self,first_name,last_name,age,country):
		"""初始化属性"""
		self.name = first_name + last_name
		self.age = age
		self.country = country	
		
	def describe_user(self):
		"""打印用户信息"""
		print("The user " + self.name.title() + " is " + str(self.age) +
		 " years old,and live in " + self.country.title() + "."
		 )		
		 
	def greet_user(self):
		"""打印欢迎信息"""
		print("Hello! " + self.name.title() + ".")

class Privileges():
	"""编写一个只有特权属性的类"""
	def __init__(self,privileges='add post'):
		self.privileges = privileges
	
	def show_privileges(self):
		print("\nYou can " + self.privileges)
		
#父类为User,子类为Admin
class Admin(User):	
	def __init__(self,first_name,last_name,age,country):
		super().__init__(first_name,last_name,age,country)
		self.privileges = Privileges()

再将该模块中的一个类添加到主模块中进行使用

from admin import Admin

#创建实例		
my_user = Admin('Bill ','Gates',24,'china')
#调用方法
my_user.describe_user()
my_user.greet_user()		
my_user.privileges.show_privileges()

(3)错误示例
如果我们没有导入某个类,但是使用了其中的方法,那么会报错。
在这里插入图片描述
5、Python标准库
我们可以使用其他程序员编好的模块,因此只需在程序开头包含一条简单的import语句即可。

练习
使用Python中自带模块collections的OrderedDict类(OrderedDict实例的行为几乎与字典相同,区别在于记录了键值对的添加顺序。)

from collections import OrderedDict

languages = OrderedDict()

languages['peter'] = 'C'
languages['jack'] = 'verilog'
languages['lucy'] = 'python'
languages['tom'] = 'ruby'

for key,value in languages.items():
	print(key.title() + " love the language " + value.title())

创建一个随机的数利用类randint

"""创建一个随机的数"""

from random import randint

class Die():
	"""模拟随机数的产生,并打印"""
	
	def __init__(self):
		self.sides = 6
		
	def roll_die(self):
		"""打印这个数"""
		x = randint(1,6)
		self.sides = x
		print("The number is " + str(self.sides))	
		
	def roll_die10(self):
		x = randint(1,10)
		self.sides = x
		print("The number is " + str(self.sides))	
		
	def roll_die20(self):
		x = randint(1,20)
		self.sides = x
		print("The number is " + str(self.sides))	
	#自己指定面数	
	def roll_die_x(self,number):
		x = randint(1,number)
		self.sides = x
		print("The number is " + str(self.sides))

die = Die()

print("6 sides")
for i in range(0,10):
	die.roll_die()
print("10 sides")
for i in range(0,10):
	die.roll_die10()
print("20 sides")
for i in range(0,10):
	die.roll_die20()
print("you show!")
for i in range(0,10):
	#指定面数为15
	die.roll_die_x(15)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值