一、函数
(一)定义函数
1、定义函数的格式
def 函数名(参数/无参可不写):
函数体
2、函数的简单调用:
依次指定函数名以及参数
例如:
def hello():
print("Hello World!")
hello()
#输出Hello World!
3、向函数传递信息
def hello(name):
print("Hello,"+name.title())
hello('zhangsan')
#输出Hello,Zhangsan!
4、实参和形参
(1)形参:函数完成其工作所需的一项信息。
(2)实参:调用函数时传递给函数的信息。
(3)关联:调用函数时,函数将实际参数传递给形式参数,并执行函数体。
(二)传递实参
1、位置实参
(1)定义:调用函数时,python必须将函数调用中的每一个实参都关联到函数定义中的一个形参。最简单的关联方式是基于实参的顺序。这种关联方式被称为位置实参。
例如:
def friend(name,age):
print('I hava a friend ,his name is '+name.title())
print("His age is "+str(age))
#zhangsan 18作为实际参数传送给name age
friend("zhangsan",18)
#I hava a friend ,his name is Zhangsan
#His age is 18
(2)使用
01、在使用时可根据需要使用任意数量的位置参数,Python将按照顺序将函数调用中的实参关联到函数定义中的形参。
02、使用时位置实参的顺序十分重要,切勿顺序错误。
2、关键字实参
(1)定义:关键字实参是传递给函数的名称——值对。即直接指定形参名称并赋值。
例如:
def friend(name,age):
print('I hava a friend ,his name is '+name.title())
print("His age is "+str(age))
#zhangsan 18作为实际参数传送给name age
friend(name="zhangsan",age=18)
#I hava a friend ,his name is Zhangsan
#His age is 18
(2)注意:使用关键字实参时,务必准确指定函数定义中的形参名。
3、默认值
(1)定义:编写函数时可给每个形参指定默认值。在调用函数中给形参提供了实参时,Python将使用指定的实参值;否则,将使用形参的默认值。
例如:
def friend(name,age=19):
#将age的默认值设为19
print("I have a friend , his name is "+name.title())
print("His age is "+str(age))
friend("zhangsan")
#只传递name一个实参,age将采用默认值19
#I have a friend , his name is Zhangsan
#His age is 19
4、等效的函数调用
01、定义:可混合使用位置实参、关键字实参和默认值,通常有多种等效的函数调用方式。
例如:
def friend(name,age=19):
print("I have a friend , his name is "+name.title())
print("His is age is "+str(age))
friend("zhangsan")
friend(name="lisi")
friend("wangmazi",18)
friend(name="wuwu",age=18)
friend(age=21,name="zhouliu")
#I have a friend , his name is Zhangsan
#His is age is 19
#I have a friend , his name is Lisi
#His is age is 19
#I have a friend , his name is Wangmazi
#His is age is 18
#I have a friend , his name is Wuwu
#His is age is 18
#I have a friend , his name is Zhouliu
#His is age is 21
02、注意:避免实参错误,例如需要实参却在调用时未进行指定。
(三)返回值
1、返回简单值
(1)定义:函数可以处理一些数据并返回一个或一组值。函数返回的值被称为返回值。
(2)使用:return语句,调用返回值的函数时,需要提供一个变量用于存储返回的值。
例如:
def max(a,b):
if(a>b):
max=a
else:
max=b
return max
number=max(90,25)
print("The max number is "+str(number))
#输出为:The max number is 90
2、让实参变成可选的
使用方法:将可选的实参的对应形参放在形参列表的最后一位并将其定义为空(字符串可定义为空字符串),在函数体中通过条件测试来判断该实参是否存在,并返回对应的值。
例如:
def animal(kinds,age,name=""):
print("I hava a "+kinds+".")
print("Let me think,its age is "+str(age)+".")
if name:
print("Its name is "+name.title()+".")
else:
print("I can't know I should call what name.")
animal("snake",5,"xiaoqing")
animal("dog",3)
#I hava a snake.
#Let me think,its age is 5.
#Its name is Xiaoqing.
#I hava a dog.
#Let me think,its age is 3.
#I can't know I should call what name.
3、返回字典
函数可返回任何类型的值,包括列表和字典等较复杂的数据结构。
例如:
def subject_score(subject,score):
subject1={'subject':subject,'score':score}
return subject1
math=subject_score('math',98)
print(math)
#{'subject': 'math', 'score': 98}
4、结合使用函数和while循环
def subject_score(subject,score):
subjects={'subject':subject,'score':score}
return subjects
print("I will help you record the scores.")
print("When you end,please Enter 'q'.")
subjects=[]
while True:
sub=input("Your subject:")
if sub=='q':
break
sc=input("Your score:")
if sc=='q':
break
subject=subject_score(sub, sc)
subjects.append(subject)
print(subjects)
输出为:
I will help you record the scores.
When you end,please Enter 'q'.
Your subject:math
Your score:65
Your subject:history
Your score:78
Your subject:q
[{'subject': 'math', 'score': '56'}, {'subject': 'history', 'score': '78'}]
(四)传递列表
(1)简单的使用
def friends(names):
print("Now I want you to konw my old friends.\n")
for name in names:
print("His name is "+name.title())
fri=['zhangsan','lisi','wangmazi']
friends(fri)
#输出为:
Now I want you to konw my old friends.
His name is Zhangsan
His name is Lisi
His name is Wangmazi
(2)在函数中修改列表
将列表传递给函数后,函数就可以对其进行修改。在函数中对这个列表的修改是永久性的。
def user_name(un_user, user):
while un_user:
users=un_user.pop()
user.append(users)
def show(user):
for users in user:
print(users.title() + " was confirmed")
us_n = ['zhangsan', 'lisi', 'wangmaizi']
us = []
user_name(us_n, us)
show(us)
输出为:
Wangmaizi was confirmed
Lisi was confirmed
Zhangsan was confirmed
(3)禁止函数修改列表
- 若想保留原有的列表则向函数传递原有列表的的副本。
- 创捷列表的副本:切片表示法 [ : ]
def user_name(un_user, user):
while un_user:
users=un_user.pop()
user.append(users)
def show(user):
for users in user:
print(users.title() + " was confirmed")
us_n = ['zhangsan', 'lisi', 'wangmaizi']
us = []
user_name(us_n[:], us)
#传递列表的副本
print(us_n)
show(us)
#输出为:
['zhangsan', 'lisi', 'wangmaizi']
Wangmaizi was confirmed
Lisi was confirmed
Zhangsan was confirmed
(五)传递任意数量的实参
- 用来解决预先不知道函数需要接受多少个实参的问题。
(1)格式:将形式参数改为*形参名
- 形参名中的*让python创建一个空元组,并将收到的所有值封装到这个元组中。
例如:
def myfriends(*friend):
print(friend)
myfriends('zhangsan','lisi','wnagmazi')
#输出为:('zhangsan', 'lisi', 'wnagmazi')
(2)结合使用位置实参和任意数量实参
- 如果要让函数接收不同类型的实参,必须在函数定义中将接纳任意数量的实参放在最后。
例如:
def like(name,*fruits):
print("This is "+name.title()+",his favorite fruit ")
cnt=0
for fruit in fruits:
cnt+=1
for fruit in fruits:
if cnt==1:
print("Only one:"+fruit)
else:
print("-"+fruit)
like('zhangsan','apple')
like('lisi','apple','strawberry','watermelon')
#输出为:
This is Zhangsan,his favorite fruit
Only one:apple
This is Lisi,his favorite fruit
-apple
-strawberry
-watermelon
(3)使用任意数量的关键字实参
格式:**形参名
- 实际让函数创造了一个空字典
def subject_score(name,age,**subjiects):
subject={}
subject['name']=name.title()
subject['age']=age
for key,value in subjiects.items():
subject[key]=value
return subject
zhangsan=subject_score('zhangsan',19,math=90,history=78)
print(zhangsan)
#{'name': 'Zhangsan', 'age': 19, 'math': 90, 'history': 78}
(六)将函数存储在模块中
1、导入整个模块
- 通过给函数指定描述性的名称,将函数存储在被称为模块的独立文件再将模块导入主程序中。
- import语句允许在当前运行的程序文件中使用模块中的代码
- 注意:若函数与主程序未在同一个包中,还需要再导入一次包
- 调用函数格式:(包名称).模块名.函数名(实际参数)
- 例如:
def make_car(name,kind,**somes):
car={}
car['name']=name
car['type']=kind
for key,value in somes.items():
car[key]=value
return car
import python练习2.make_car
new_car=python练习2.make_car.make_car('BBW',720,color='bule',price='50000$')
print(new_car)
#{'name': 'BBW', 'type': 720, 'color': 'bule', 'price': '50000$'}
(2)导入特定的函数
- 格式:from 包名.模块名 import 函数名
- 例如:
def show(name):
print("This is my new "+name.title())
from python练习2.make_car import show
show('BBW')
##输出:This is my new BBW
(3)使用as指定别名:
- 若函数名或模块名出现冲突可使用as指定别名
- 格式:函数名/模块名 as 新名称
- 例如:
import python练习2.make_car as p
new_car=p.make_car('BBW',720,color='bule',price='50000$')
print(new_car)
from python练习2.make_car import show as s
s('BBW')
#{'name': 'BBW', 'type': 720, 'color': 'bule', 'price': '50000$'}
#This is my new Bbw
(4)导入模块中的所有函数
- 使用(*)运算符可以让Python导入模块中的所以有函数
- 例如:
from python练习2.make_car import *
new_car=make_car("QiRui","A5",color='White',price='10000$')
print(new_car)
show("QiRui")
#{'name': 'QiRui', 'type': 'A5', 'color': 'White', 'price': '10000$'}
#This is my new Qirui
(5)函数编写指南
- 编写函数时,应给函数指定描述性名称,且只在其中使用小写字母和下划线
- 每个函数都应包含简要的阐述其功能的注释,该注释应紧跟在函数定义后并采用文档字符串格式。
- 给形参指定默认值时,等号两边不要有空格,对于函数调用中的关键字实参同样如此。
- 如果程序或模块包含多个函数,可使用两个空行将相邻的函数分开。
-
所有的impor语句都应该放在文件开头,除非文件开头使用了注释。
二、类
(一)面向对象和类
- 面向对象是相对于面向过程语言提出的。c语言是典型的面向过程语言,需要程序员具体到每一个步骤。Java是典型面向对象的语言,它简化了具体步骤,直接面向某个对象进行编程。
- 例如,以启动汽车为例。C:打卡车门——>插入车钥匙——>踩离合.... Java:启动我的汽车
- 类:一类具体抽象事物的代称。对象:一类事物的某个具体实例。
- 例如:狗是一个类,我的一只二哈是一个对象
(二)创建和使用类
1、创建一个简单的类
class Dog():
#class代表定义一个类,类名称的首字母必须大写
#类中的函数被称为方法,与普通函数的区别在于调用方式上。
def __init__(self,name,age):
self.name=name
self.age=age
#定义一个默认方法,并初始化name与age。在写默认方法时,self必须位于形参的第一个。
#self:每个与类相关联的方法调用都将自动传递实参self,self是一个指向实例本身的引用,让实例能够访问类中的属性和方法。
#在实参传递时,self会自动传递,我们只需要给其后的形参提供值。
def sit(self):
print(self.name.title()+" is now sitting.")
def show(self):
print(self.name.title()+"'s age is "+str(self.age))
#以self为前缀的变量都可以供类中的方法进行使用,还可以通过类中的任何实例来访问这些变量。
2、根据类创建一个实例
#1、访问属性
#创建对象的格式 :对象名 = 类名(实参)
my_dog = Dog('wangcai',6)
#创建一个名为wangcai的实例,在调用任何方法时,python会自动调用默认方法。因此可以使用name和age两个变量
print("This is my dog ,it's "+my_dog.name.title())
print("It's age is "+str(my_dog.age))
#在调用类中的方法时需要加上对象(也就是实例)作为前缀。也就是句点表示法。
print("================================================")
#2、调用方法
my_dog.sit()
my_dog.show()
#调用方法时同样使用句点表示法。
print("================================================")
#3、创建多个实例(对象)
you_dog=Dog('doudou',5)
friend_dog=Dog('dingding',3)
girlfri_dog=Dog('doudou',5)
#即使属性相同,python依然会创建一个实例
you_dog.show()
friend_dog.show()
girlfri_dog.show()
输出为:
This is my dog ,it's Wangcai
It's age is 6
================================================
Wangcai is now sitting.
Wangcai's age is 6
================================================
Doudou's age is 5
Dingding's age is 3
Doudou's age is 5
Process finished with exit code 0
(三)使用类和实例
以一个car类为例来说明以下两个内容:
- 给属性指定默认值
- 修改属性的值(直接修改和通过方法进行修改)
class Car():
#定义一个car类并添加默认方法
def __init__(self,make,model,year):
#定义一个默认方法用于汽车初始化的描述
self.make=make
self.model=model
self.year=year
#给一个属性指定默认值,定义一个里程显示的变量并设定值为10000
self.meter_show=0
def show(self):
show_name=str(self.year)+" "+self.make+" "+str(self.year)
def show_meter(self):
print("This car has "+str(self.meter_show)+" miles on it !")
#定义一个方法用于修改mete_show的值
def change(self,new):
#添加一些实用功能
if new>=self.meter_show:
print("This car has " + str(new) + " miles on it !")
else:
print("You can't do this thing to lie us !")
def increment(self,newmile):
if newmile>=0:
self.meter_show+=newmile
print("You use the car pass "+str(self.meter_show)+" miles !")
else:
print("Don't do this !")
#定义一个实例
my_newcar=Car("Qirui","A5",2020)
my_newcar.show()
my_newcar.show_meter()
print("==============================================================")
#修改属性的值
#1、直接修改
my_newcar.meter_show=10000
my_newcar.show_meter()
print("==============================================================")
#2、通过方法进行修改(在类中定义一个方法进行修改)
my_newcar.change(133000)
my_newcar.change(5000)
print("==============================================================")
#3、通过方法对属性的值进行递增(在类中定义一个方法)
my_usecar=Car("Jili","Dihao",2019)
my_usecar.increment(100)
my_usecar.increment(-1000)
输出为:
This car has 0 miles on it !
==============================================================
This car has 10000 miles on it !
==============================================================
This car has 133000 miles on it !
You can't do this thing to lie us !
==============================================================
You use the car pass 100 miles !
Don't do this !
Process finished with exit code 0
(四)继承
1、继承定义及特点:
- 编写的类是另一个类的现成类的特殊版本,可使用继承。
- 一个类继承另一个类时,它将自动获得另一个类的所有属性和方法;原有的类成为父类,而新类成为子类。
- 子类继承其父类的属性和方法,同时给还可以定义自己的属性和方法。
2、创建和使用子类
- 下面将以一个具体的代码实例来阐述相关的方法
#定义一个父类
class Car():
def __init__(self,make,model,year):
self.make=make
self.model=model
self.year=year
self.meter_show=0
def show(self):
show_name=str(self.year)+" "+str(self.make)+" "+str(self.model)
return show_name.title()
def show_meter(self):
print("This car has "+str(self.meter_show)+" miles on it !")
def new_show(self,new):
if new>=self.meter_show:
self.meter_show=new
else:
print("Don't do this !")
def increment(self,miles):
self.meter_show+=miles
def place(self):
print("This car is made from China. ")
#编写一个子类,将其父类写到类名称后的括号中,注意,创建子类时父类必须包含在当前文件当中且在子类前面。
class new_car(Car):
# 初始化父类的属性
def __init__(self,make,model,year):
#父类也称为超类,super函数让子类继承父类的相关属性
super().__init__(make,model,year)
#初始化新汽车特有的属性,并定义一个子类独有的方法。新添加子类的属性和方法仅子类独有,新创建的子类没有这些方法。
self.max_seepd=280
def seepd(self):
print("My new car has a more quick speed: "+str(self.max_seepd))
#宝马车产自德国而不是中国故需要重新定以一个方法
def new_place(self):
print("This car is from Germany.")
#在子类中创建一个实例
my_newcar=new_car("BBW",750,2020)
#因为子类已经从父类中继承相关方法,可以直接调用
print("Look my new car\n"+my_newcar.show())
#调用子类的特有方法
my_newcar.seepd()
#重写父类的方法:将子类中重新定义的方法与父类方法重名。
my_newcar.new_place()
#输出为:
Look my new car
2020 Bbw 750
My new car has a more quick speed: 280
This car is from Germany.
- 在创建子类的时候,可以将子类当中独有的属性和方法重新创建一个类,例如上面的代码
#定义一个父类
class Car():
def __init__(self,make,model,year):
self.make=make
self.model=model
self.year=year
self.meter_show=0
def show(self):
show_name=str(self.year)+" "+str(self.make)+" "+str(self.model)
return show_name.title()
def show_meter(self):
print("This car has "+str(self.meter_show)+" miles on it !")
def new_show(self,new):
if new>=self.meter_show:
self.meter_show=new
else:
print("Don't do this !")
def increment(self,miles):
self.meter_show+=miles
def place(self):
print("This car is made from China. ")
#创建一个子类的特有类
class mynew():
#仍然需要进行初始化
def __init__(self,max_seppd=280):
self.max_seepd=max_seppd
def seepd(self):
print("It's max seppd "+str(self.max_seepd))
def new_place(self,place):
print("This car is made from "+place.title())
#创建一个子类
class new_car(Car):
#初始化父类的属性,再初始化子类的属性。
def __init__(self,make,model,year):
super().__init__(make,model,year)
#在子类中添加一个self.max_seepd的属性,创建一个mynew的新实例,并将该实例储存在新属性当中。
#每当方法_init_被调用时都将执行该操作,因此每创建一个new_car实例,都包含一个自动创建的mynew实例。
self.newcar=mynew()
my_newcar=new_car("BBW",750,2020)
print(my_newcar.show())
#调用该属性,因为该属性存储了mynew类,因此可以调用mynew类中的方法
my_newcar.newcar.seepd()
#输出为:
2020 Bbw 750
It's max seppd 280
- 可使用类与对象的相关知识模拟实物
(五)导入类
- 存储对应的父类在一个模块中,并创建另一个模块导入父类进行使用,以实际代码为例进行分析。
class animais():
# 创建一个名为animals的父类
#初始化父类的属性
def __init__(self,kind,age):
self.kind=kind
self.age=age
#定义父类方法
def show(self):
print("This is my pet ,it's a "+self.kind)
print("My "+self.kind+"'s age is "+str(self.age))
#一个模块中可储存多个类并进行导入
class life():
#初始化类的属性
def __init__(self,year):
self.year=year
def show_pet(self,buy):
print("I buy this pet in "+str(buy)+" and now I live wiht it for "+str(self.year)+'years')
def sit(self):
print("Look, my pet is sitiing!")
#1、导入单个类
#导入定义的父类animals,格式:form 模块名 import 父类
#from python练习2.animal import animais
#再次导入模块中另一个类
#from python练习2.animal import life
#2、导入多个类时可使用以下的格式,用逗号将对应的类分隔
from python练习2.animal import animais,life
#导入后创建一个实例,调用父类的方法
my_cat=animais('cat',3)
my_cat.show()
my_cat=life(2)
my_cat.show_pet(2018)
my_cat.sit()
#3、也可以导入整个模块并使用句点法访问需要的类
import python练习2.animal
#导入后创建一个实例,调用父类的方法
print("=======================")
from python练习2 import animal
#导入整个模块后创建一个实例
my_dog = animal.animais("dog",6)
my_dog.show()
my_dog = animal.life(5)
my_dog.show_pet(2015)
#4、可以导入模块中的所有类使用如下语法
# from 模块名 import*
from python练习2.animal import*
my_pig = animais("pig",2)
#输出为:
This is my pet ,it's a cat
My cat's age is 3
I buy this pet in 2018 and now I live wiht it for 2years
Look, my pet is sitiing!
=======================
This is my pet ,it's a dog
My dog's age is 6
I buy this pet in 2015 and now I live wiht it for 5years
Process finished with exit code 0
#5、有时候模块中存储的类过多,我们可以将类分开存储到不同的模块中,并在一个模块中导入另一个模块
from python练习2 import animal
class Dog():
def __init__(self,name):
self.name='erha'
def eat(self):
print("Look,my "+self.name.title()+" is eating food !")
#导入不同的模块
from python练习2.animal import*
from python练习2.my_erha import*
my_pet = animais("erha",2)
my_pet.show()
my_pet = Dog("wangcai")
my_pet.eat()
输出为:
This is my pet ,it's a erha
My erha's age is 2
Look,my Erha is eating food !
Process finished with exit code 0
(六)python标准库
- python标准库是一组模块,pycharm中可以使用标准库中的任何函数和类,使用时只需要用impo语句进行调用即可。
- 下面以collections中的一个类OrderedDict为例进行标准库的调用
#使用impory语句调用标准库
from collections import OrderedDict
#OrderDict实例的行为几乎与字典相同,区别只在于记录了键——值对的添加顺序
#OrderDict是一个类,创建的虽然是字典,但后缀为圆括号而不是大括号,这与使用类的方法一致
favorite_fruits=OrderedDict()
favorite_fruits['zhangsan']='banana'
favorite_fruits['lisi']='peach'
favorite_fruits['wangmazi']='apple'
favorite_fruits['wangerxiao']='watermelon'
for name,fruit in favorite_fruits.items():
print(name.title()+"'s favorite is "+fruit+' .')
输出为:
Zhangsan's favorite is banana .
Lisi's favorite is peach .
Wangmazi's favorite is apple .
Wangerxiao's favorite is watermelon .
Process finished with exit code 0
(七)类的编码风格
- 类名采用驼峰命名法,即将类名中的每个单词中的每个单词首字母都大写,而不使用下划线。实例名和模块都采用小写格式,并在单词之间加上下划线。
- 对于每个类,都应紧跟在类定义后面一个文档字符串。这种文档字符串紧要地描述类功能,并遵循编写函数的文档字符串时采用的格式约定。每个模块也都应包含一个文档字符串,对其中的类可用于做什么进行描述。
- 可使用空行来组织代码,但不要滥用。在类中,可使用一个空行来分隔方法;而在模块中,可使用两个空行来分隔类。
- 需要同时导入标准库中的模块和你编写的模块时,先编写导入标准库模块的import语句,再添加一个空行,然后编写导入你的自己编写的模块的import语句。在包含多条import语句的程序中,这种做法让人更容易明白程序使用的各个模块都来自何方。