Python学习笔记_2
一、函数
1. 定义:
SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。def 函数名(参数1,参数2): ----(参数可有可无)
语句体
return 变量 ----(return可有可无)
2. 调用:
函数名
变量=函数名(参数1,参数2) ----(变量,参数可有可无)
① 调用 ②传参 ③ 接收返回值
3. 举例:
①第一种:无参无返回值
# 定义函数calc
def calc():
a = int(input('请输入第一个数:'))
b = int(input('请输入第二个数:'))
c = a + b
# print('结果为:',c)
print('结果为:%d'%c)
# 调用
calc()
运行结果为:
请输入第一个数:1
请输入第二个数:3
结果为:4
② 第二种:无参有返回值
def calc():
a = int(input('请输入第一个数:'))
b = int(input('请输入第二个数:'))
c = a + b
return c
# 调用
# print(calc())
result = calc()
print(result)
③ 第三种:有参有返回值
def calc(x,y):
c = x + y
return c
a = int(input('请输入第一个数:'))
b = int(input('请输入第二个数:'))
result = calc(a,b)
print(result)
4. 练习:设计一个计算器
① 输入两个数,自动实现加减乘除
x = int(input('请输入第一个数:'))
y = int(input('请输入第二个数:'))
def add():
z = x + y
return z
def sub():
z = x - y
return z
def mul():
z = x * y
return z
def div():
z = x / y
return z
print('两数相加为:',add())
print('两数相减为:',sub())
print('两数相乘为:',mul())
print('两数相除为:',div())
运行结果为:
请输入第一个数:6
请输入第二个数:2
两数相加为: 8
两数相减为: 4
两数相乘为: 12
两数相除为: 3.0
② 进阶:根据用户输入的计算符号计算结果
def calc():
x = int(input('请输入第一个数:'))
y = int(input('请输入第二个数:'))
z = input('请输入运算符号:+ - * /:')
if z == '+':
result = x + y
print('两数相加为:',result)
elif z == '-':
result = x - y
print('两数相减为:',result)
elif z == '*':
result = x * y
print('两数相乘为:',result)
elif z == '/':
try:
result = x / y
print('两数相除为:',result)
except ZeroDivisionError:
print('除数不能为0!')
else:
print('运算符号输入错误,请重新输入!')
calc()
5. 参数的几种类型:
① 位置参数:调用函数时根据函数定义的参数位置来传递参数
def person(name,sex):
sex_dict = {1:'先生',2:'女士'}
print('hello %s %s,welcome~'%(name,sex_dict.get(sex,'女士')))
person('baby',2)
运行结果为:
hello baby 女士,welcome~
注意:位置参数的两个参数的顺序必须一一对应,且少一个参数都不可以
② 默认参数:用于定义函数,为参数提供默认值,调用函数时可传可不传该默认参数的值
注意:定义默认参数时,必选参数在前、默认参数在后(包括函数定义和调用),否则python解释器会报错,且默认参数必须执行不变对象!
1)默认参数指向可变对象时:(保留了上次执行的结果)
def add_end(L = []):
L.append('end')
return L
print(add_end())
print(add_end())
运行结果:
['end']
['end', 'end']
2)默认参数指向不变对象时:
def add_end(L = None):
if L is None:
L = []
L.append('end')
return L
print(add_end())
print(add_end())
运行结果:
['end']
['end']
③ 可变参数:定义函数时,有时候我们不确定调用的时候会传递多少个参数(不传参也可以)。此时,可用位置参数,或者关键字参数,来进行参数传递
我们传进的所有参数都会被args变量收集,它会根据传进参数的位置合并为一个元组(tuple),args是元组类型,这就是位置传递
1)
def calc(*args):
print(*args) # *args打印出来是一个一个的整型的数
print(args,type(args)) # args默认保存为元组,打印出来是一个元组
for i in args:
print('传入的值分别为:',i)
# 可变参数传参形式1 - 常用(通过引用的方式必须带*)
m = [1,2,3]
calc(*m)
运行结果:
1 2 3
(1, 2, 3) <class 'tuple'>
传入的值分别为: 1
传入的值分别为: 2
传入的值分别为: 3
2)
def calc(*args):
print(*args) # *args打印出来是一个一个的整型的数
print(args,type(args)) # args默认保存为元组,打印出来是一个元组
for i in args:
print('传入的值分别为:',i)
n = (3,4,5)
calc(*n)
3)
def calc(*args):
print(*args) # *args打印出来是一个一个的整型的数
print(args,type(args)) # args默认保存为元组,打印出来是一个元组
for i in args:
print('传入的值分别为:',i)
# 可变参数传参形式2
calc(1,2,3)
④ 关键字参数:用于函数调用,通过“键-值”形式加以指定。可以让函数更加清晰、容易使用,同时也清除了参数的顺序需求。
有位置参数时,位置参数必须在关键字参数的前面,但关键字参数之间不存在先后顺序
kargs是一个字典(dict),收集所有关键字参数
def person(name,age,**kwargs):
print('name',name,'age',age,kwargs)
print(kwargs,type(kwargs))
person('xiaoming',21,sex = 'male',color = 'blue')
person('xiaoming',21) # 可变参数和关键字参数可以不传
person('xiaoming',21,sex = 1)
person('xiaoming',21,sex = 'male')
总结:
可变参数允许你传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple。
而关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict。
关键字参数有什么用?
它可以扩展函数的功能。比如,在person函数里,我们保证能接收到name和age这两个参数,但是,如果调用者愿意提供更多的参数,我们也能收到。试想你正在做一个用户注册的功能,除了用户名和年龄是必填项外,其他都是可选项,利用关键字参数来定义这个函数就能满足注册的需求。
和可变参数类似,也可以先组装出一个dict,然后,把该dict转换为关键字参数传进去:
def person(name,age,**kwargs):
print('name',name,'age',age,kwargs)
extra = {'city':'beijing','job':'Engineer'}
person('xiaoming',25,**extra)
运行结果为:
name xiaoming age 25 {'job': 'Engineer', 'city': 'beijing'}
6. 异常处理:
① 已知类型:try ... except
def calc(a,b):
try:
print(a/b)
except ZeroDivisionError:
print('除数不能为0!')
a = int(input('-'))
b = int(input('-'))
calc(a,b)
运行结果为:
-2
-0
除数不能为0!
② 未知类型:https://www.cnblogs.com/zln1021/p/6106185.html
def calc(a,b):
try:
print(a/b)
except Exception: # BaseException
print('除数不能为0!')
a = int(input('-'))
b = int(input('-'))
calc(a,b)
③ 多重异常:
def calc(a,b):
try:
print(a/b)
except NameError:
print('该对象未申明')
except ZeroDivisionError:
print('除数不能为0')
a = int(input('-'))
b = int(input('-'))
calc(a,b)
④ 最终处理:
def calc(a,b):
try:
print(a/b)
except NameError:
print('该对象未申明')
except ZeroDivisionError as msg:
# print(msg)
print('除数不能为0',msg)
finally:
print('程序执行完毕')
a = int(input('-'))
b = int(input('-'))
calc(a,b)
⑤ else:在程序没有抛出异常的时候,继续执行else语句
def calc(a,b):
try:
print(a/b)
except NameError:
print('该对象未申明')
except TypeError as msg:
print(msg)
else:
print('程序执行完毕!')
a = int(input('请输入第一个数:'))
b = int(input('请输入第二个数:'))
calc(a,b)
⑥抛出异常:异常必须为exception的子类
raise TypeError('类型错误')
def calc(a,b):
try:
print(a/b)
except NameError:
print('该对象未申明')
# 查看异常后不做处理继续抛出异常
raise
except ZeroDivisionError as msg:
# print(msg)
print('除数不能为0',msg)
else:
print('程序执行完毕')
a = int(input('-'))
b = int(input('-'))
calc(a,b)
⑦ 练习:name没有定义,type异常,并抛出是何种异常
def calc(a,b):
try:
print(a/b)
except NameError as msg:
print('该对象未申明',msg)
raise
except TypeError as msg:
print(msg)
raise
else:
print('程序执行完毕!')
a = int(input('请输入第一个数:'))
b = int(input('请输入第二个数:'))
calc(a,b)
7. 文件IO:
文件操作流程:
① 找到文件 :新建文件new --> file-->data.txt,查看文件路径:右键data,选择Show in Explorer(路径支持绝对路径和相对路径)
data文件内容如下:
a,b,c
tom,lucy,lily
1,2,3
② 打开文件:(文件路径和打开模式)
打开文件的模式有:
- r:只读模式(默认)。
- w:只写模式(不可读;不存在则创建;存在则删除内容)
- a:追加模式 -- append(可读;不存在则创建;存在则只追加内容)
"+" 表示可以同时读写某个文件
- r+:可读写文件(可读;可写;可追加)
- w+:写读
- a+:同a
f = open('F:\Code\VIPtest2\data.txt','r')
③ 操作文件:读、写
读取文件所有内容:print(f.read()) -- 文件大时不要用
读取指定长度字节的数据:print(f.read(4)) -- 读取前4个字节的内容
读取整行:print(f.readline()) -- 读取光标所在位置的整行
读取前5行:
for i in range(5):
print(f.readline())
如果需要读取5-10行,中间加个if判断即可
读取所有行:print(f.readlines()) -- 列表形式输出
运行结果:['a,b,c\n', 'tom,lucy,lily\n', '1,2,3\n', '\n']
写:
f = open('F:\Code\VIPtest2\data2.txt','r+')
f.write('hello python!\n')
f.write('welcome~')
f.close()
④ 关闭文件:f.close()
作业:只取出data中的数字并写入另外的文件
思路:
① 读取文件中的所有数据 -- readlines
② 从列表中找出含有的数字
判断列表中的每一个元素是否含有数字 -- 将列表中的每一个元素(数据的行)取出来,作为一个小的列表
判断每一个小的列表是否含有数字 isdigit(),如果是数字,则追加到一个新的列表
③ 排序、写入
data:
a,b,c
tom,lucy,lily
1,3,9,6,8,4,5
代码:
f = open('F:\Code\VIPtest2\data.txt','r')
lines = f.readlines()
# print(lines)
lists = []
for l in lines:
# print(l)
s = l.split(',') # 切片
# print(s)
for m in s:
if m.strip().isdigit(): # 判断是否为数字
lists.append(m.strip())
else:
continue
for i in range(1,len(lists)): # 冒泡排序
for j in range(0,len(lists)-i):
if lists[j] > lists[j+1]:
lists[j],lists[j+1] = lists[j+1],lists[j]
print(lists)
f1 = open('F:\Code\VIPtest2\data3.txt','r+')
f1.write(str(lists))
f.close()
8. 模块和包:
① 模块:模块是一个包含所有你定义的函数和变量的文件,其后缀名是.py,模块可以被别的程序引入,以使用该模块中的函数等功能,这也是使用python标准库的方法。
Mymodule:
def fun1():
print('我是fun1函数')
def fun2():
print('我是fun2函数')
print('name的值为:',__name__)
# 每个模块都有一个__name__属性,当其值为:'__main__'时,表明该模块自身在运行,否则是被引入
if __name__ == '__main__':
fun1()
fun2()
__name__的作用:一个模块被另一个程序第一次引入时,其主程序将运行。如果我们想在模块被引入时,模块中的某一程序块不执行,我们可以用__name__属性来使该程序块仅在该模块自身运行时执行
② 包:当一个目录内含有__init__.py文件时,就可以视该目录为一个包。
③ 调用包和模块:
第一种调用方式:import 模块名/ 包名(只能导入名称)
右键practice-->mark directory as->resource root(将当前路径加入python查找的默认路径
如果通过import调用,使用包内的方法需要通过包名.函数名的形式
Mymodule.fun1()
第二种调用方式:from 包名 import 模块名
from ... import的形式导入,from后面只能跟包和模块名,不能跟函数名,import后面跟函数或者类名
绝对导入:from practice import module
from Mymodule import fun1
通过from-import的形式可以直接使用函数名
fun1()
fun2()
第三种调用方式:相对导入
from .database import Database # 点号表示使用当前路径的database模块
from ..database import Database # 使用两个点号表示访问上层的父类
第四种调用方式:通过import* 可以导入多个函数
from Mymodule import *
二、面向对象的类、属性、方法
1. 基础:
类:具有相同的特性,且能够完成某些动作的事物组成的一个集合
属性:类中的事物所具有的特性,趋于静态
方法:类中的事物所能够完成的动作或功能,趋于动态
实例/对象:类中某一个具体的对象或实例
实例化:定义类中某一个对象的过程
2. 类的定义:
class 类名(object):
属性
方法
注意:属性和方法可以为空,里面直接写pass即可,表示是一个空类
举例:
3. 类的实例化:
变量=类名('xx') ---是否需要传参就看__init__方法中除了self是否还有其他参数
4. 类中方法的调用:
实例名.方法名('xx') ---是否需要传参就看该方法中除了self是否还有其他参数
练习:
① 定义一个学生类:Student、内部含有一个方法:study,实现打印:小明学习xx课程
② 定义一个类名:Student—学生、类内部含有一个属性:sno—学号,一个方法:study—学习,实现打印:学号为xx的学生,学习xx课程
5. 继承:为了提高代码的复用性,可以通过继承来减少属性和方法的编写
语法:继承谁就在括号中写谁-类名
例子:
练习:
定义一个Teacher类,继承Person类,拥有自身的属性工号gh,自身的方法:teach教课(课程);
① 实现gh为xx的老师,教xx课
② 实现gh为xx老师,在xx上班,一月工资xx
③ 名字是xx,工号为xx的老师,吃饭
6.重写:当继承的父类方法不满足自身需要的时候,我们可以重写该父类的方法,注意,必须同名
例子:
调用父类的方法:
多重继承的注意事项:
7.多态:多态性是指具有不同功能的函数可以使用相同的函数名,这样就可以用一个函数名调用不同内容的函数。在面向对象方法中一般是这样表述多态性:向不同的对象发送同一条消息,不同的对象在接收时会产生不同的行为(即方法)。也就是说,每个对象可以用自己的方式去响应共同的消息。所谓消息,就是调用函数,不同的行为就是指不同的实现,即执行不同的函数。
8.私有属性和私有方法
类的私有属性
__abc:两个下划线开头,声明该属性为私有,不能在类的外部被使用或直接访问。在类内部的方法中使用时 self.__abc。
类的方法
在类的内部,使用 def 关键字来定义一个方法,与一般函数定义不同,类方法必须包含参数 self,且为第一个参数,self 代表的是类的实例。
self 的名字并不是规定死的,也可以使用 this,但是最好还是按照约定是用 self。
类的私有方法
__method:两个下划线开头,声明该方法为私有方法,只能在类的内部调用 ,不能在类的外部调用。self.__ methods。
