day06-特殊参数/文件IO/面向对象
目录
一、默认参数和关键字参数
二、可变参数
三、递归函数
四、文件I/O
五、文件I/O练习
六、面向对象
一、默认参数和关键字参数
1. 默认参数#
形参设定默认值 称为 默认参数
调用函数时,如果没有传入默认参数对应的实参,则实参使用默认值
默认参数在调用的时候可以不传递,也可以传递
def sayHello(name='林青霞'):# 形参 没有默认数据的参数定义在有默认数据的参数后面
'''
给女神打招呼
:param name:
:return:
'''
print('hello %s'%(name))
# 调用时不传递参数,使用默认值
sayHello()
# 调用时传递参数
sayHello('高圆圆')
注意:默认参数一定要在参数的最后
2. 关键字参数#
调用函数时,实参可以指定对应的形参,称为 关键字参数
def sayHello(name,age,score):
print('姓名:%s,年纪:%d,分数:%f'%(name,age,score))
sayHello(name='林青霞',age=60,score=70.5)
#使用关键字参数调用可以改变传递参数的顺序
# 改变参数传递的顺序
sayHello(score=70,age=30,name='高圆圆')
3. 默认参数作用-代替方法重载#
网络请求是开发中最常见的需求
通常一个网络请求包含:请求地址、请求方式等
#通过一个函数实现网络请求的GET和POST
def sendRequest(path,method='GET'):
# 发送网络请求
print('请求地址:%s,请求方式:%s'%(path,method))
# 30种请求 GET:25 POST:5
# 请求新闻列表
sendRequest('http://www.toutiao.com')
# 登录
sendRequest('http://toutiao.login.com','POST')
二、可变参数
1. 可变参数args#
可变参数需要添加*,用于接收任意数量的相同类型的参数
def sum(*args):# 形参能够接收任意个长度的数据
print(*args)
# 调用可变参数的函数
sum(10,20,30)
sum(10,20,30,40)
运行结果:
可变参数的本质是 将传递的参数包装成了元组
2. 可变参数kwargs#
可变参数还有一种形式 可以接收不存在的关键字参数
定义参数时需要在变量名前添加两个*
def func(**kwargs):# kwargs 接收不存在的关键字参数
pass
# 调用不存在的关键字参数函数
func(name = '张三',age = 30,score=70)
3. 传递元组给可变参数args#
可以传递元组给可变参数args,需要在元组前加上*进行解包操作
#传递元组给可变参数args
def func(*args):
print(args)#(10,20,30)
t = (10,20,30)
# 传递元组
func(*t) #需要在元组前加上*进行解包操作
4. 传递字典给可变参数kwargs#
在字典的前面加上**的作用是将字典中的元素解包成一个一个的不存在的关键字参数传递给函数
def func(**kwargs):
print(kwargs)
d = {'name':'张三','age':40}
# 传递字典给可变参数kwargs
func(**d)
三、递归函数
1.递归简介#
递归指的是把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解
如果 一个函数在内部调用其本身,这个函数就是 递归函数
递归的好处是:只需少量的程序就可描述出解题过程所需要的多次重复计算
2. 递归求阶乘#
递归最经典的案例是求n的阶乘
例:5的阶乘:12345
分析:
如果传递的是1,1的阶乘为1
如果传递的是大于1的数,n的阶乘就等于n乘以n-1的阶乘
def func(n):
'''
求n的阶乘
:param n: 需要求的阶乘
:return: n的阶乘
'''
if n==1:
return 1
else:
return n*func(n-1)
t=func(5)
print(t)
四、文件I/O
1. 文件I/O简介#
IO是两个单词的缩写,分别是Input和Output,输入和输出
IO包含控制台IO以及文件IO
文件I/O的基本流程
打开文件
文件读写
关闭文件
2. 打开文件#
使用open函数,可以打开一个已经存在的文件,或者创建一个新文件
f = open(文件名,访问模式)
文件名:文件的相对路径或者绝对路径
访问方式:文件的访问方式有读、写、追加
打开文件
f = open('a.txt')
如果没有传入打开模式,默认访问模式为r只读模式
3. 关闭文件#
可以使用f.close()方法关闭文件
f.close()
注意:
一定要保证文件操作完之后要关闭掉,因为程序能打开的文件数量是有上限的,并且不关闭文件会造成内存泄漏
4. 文件读取#
read读取
read方法读取
格式为:
data = f.read(num)
参数num:默认-1,读取整个文件内容
可以指定num,则读取num个数据
读取整个文件内容
result = f.read()
读取5个数据
result = f.read(5)
readline
readline指的是读取一行
result = f.readline()
也可以指定读取一行n个数据
result = f.readline(15)
readlines
readlines指的是读取整个文件,返回每一行数据的列表
result = f.readlines()
5. 文件写入#
write
write写入字符串到文件中
f.write('hello world')
writelines
writelines可以将容器中数据写入到文件中
l = ['bill','gates','tom']
# 将列表中数据写入到文件中
f.writelines(l)
6. 绝对路径和相对路径#
文件路径分为两种:相对路径和绝对路径
绝对路径
绝对路径指的是在电脑硬盘上真正保存的路径 绝对路径在不同的操作系统上写法是不一样的
如下就是绝对路径写法:
D:\codespace\python4\FristPython\a.txt
绝对路径的缺点
绝对路径写起来比较麻烦
如使用的项目文件移动了,那绝对路径就变化了,就需要重新修改
相对路径
相对路径就是相对于当前目录的路径 相对路径用**.代表当前目录**,使用**…代表上一级目录** 如果是当前路径可以省略./
例如,当前文件夹下的a.txt:
./a.txt
# 简写
a.txt
上一级目录下的b.txt
../b.txt
五、文件I/O练习
1. 制作文件备份#
需求:
输入文件的名字,然后程序自动完成对文件进行备份
# 1.输入文件名 a.txt 默认文件已存在
inputName = input('请输入文件名:')
# 2.创建新文件 文件名: a[备份].txt
#以.为分割,找到.索引
index = inputName.rfind('.')
copyName = inputName[:index] + '[备份]' +inputName[index:]
#测试新文件名
print(copyName)
# 3.读取文件,写入到复制的新文件中
# 打开源文件
inputFile = open(inputName)
# 打开复制的文件
copyFile = open(copyName,'w')
'''
# 第一种方法:小文件备份
#读取输入文件
str=inputFile.read()
#写入到新的文件中
copyFile.write(str)
'''
"""
#------------------ 第2种方法:大文件备份 ------------------"""
#不会像小文件那样全部读入,再写入
# 该方法可以防止文件过大时造成内存溢出,读一行写一行,直到读取内容为空停止读取写入
#特殊情况:如果某一行出现特别多字节,可以限定一次只读1024个字节,可以防止溢出
#line = inputFile.readline(1024)
line = inputFile.readline()
while line: #判断是否为空
# 有数据,写入文件
copyFile.write(line)
# 读取一行
line = inputFile.readline()
# 关闭文件
inputFile.close()
copyFile.close()
2. 文件统计#
需求:
输入一个文件名,统计文件中代码行数、注释行数、空行数
并输出代码以及注释
分析:
1.输入文件名a.txt
2.打开文件
3.统计 readline
空行 空
注释行数 去空格 #开头
代码行数
# 1.输入文件名 a.txt
fileName = input('请输入要统计的文件名:')
# 2.打开文件
f = open(fileName,encoding='utf-8')
# 3.统计 readline
# 空行 空
# 注释行数 去空格 #开头
# 代码行数
# 定义三个变量保存空行 注释行数 代码行数
emptyCount = 0
commandCount = 0
codeCount = 0
"""------------------ 统计 ------------------"""
line = f.readline()
# str = ' '
while line:
if not line.strip():
emptyCount += 1
elif line.strip().startswith('#'):
commandCount += 1
else:
codeCount += 1
# 读取下一行
line = f.readline()
print('代码数:%d,空行数:%d,注释数:%d'%(codeCount,emptyCount,commandCount))
# 4.关闭文件
f.close()
六、面向对象
1. 面向对象和面向过程思想#
面向对象和面向过程都是一种编程思想,就是解决问题的思路
面向对象:OOP(Object Oriented Programming)
常见的面向对象语言包括:java c++ go python koltin
面向过程:POP(Process Oriented Programming)
面向过程语言代表是c语言
例:
我们看同一个问题,面向过程和面向对象是怎么解决的?
中午想吃西红柿炒鸡蛋怎么办呢?
面向过程解决问题必须要知道完成这个功能每一步的操作
面向过程思想,强调的是过程(动作)
而完成这个功能我们充当的角色是执行者的角色
面向对象思想
同样是中午想吃西红柿炒鸡蛋,
直接到饿了么上下个单,老板就把西红柿炒鸡蛋做好送过来了
餐馆老板具备做西红柿炒鸡蛋的功能,直接调用他的功能即可,不需要知道具体的流程
面向对象思想:不再关注具体的过程
功能里面充当的角色是指挥者的角色
面向过程和面向对象的总结
面向对象,强调的是对象(实体)
面向对象是一种思想,更加符合人的思维习惯
面向对象使复杂的问题简单化了
面向对象的出现,让曾经在过程中的执行者,变成了对象中的指挥者
2. 类和对象#
类和对象是面向对象非常重要的概念
类是描述了一种类型(相当于图纸)
对象是这个类型的具体实现(相当于图纸具体实现)
思考:
狗和旺财,哪个是类,哪个是对象?
狗是一个类型,属于类
旺财是狗的实现,属于对象
定义类和创建对象
类的定义格式:
class 类名:
pass
创建对象
对象名 = 类名()
代码演示:
# 定义类
class Person:
pass
# 创建对象
p1 = Person()
3. 类的组成#
类可以描述世间万物
类都需要有类名,也应该具备一些静态属性和动态的行为
类的关键字:class
类的名称:类名
类的属性:一组数据
类的方法:允许进行操作的方法(行为)
人Person类应该具备什么属性和行为呢?
属性:姓名(name) 、年纪(age)
方法:跑(run)、说话(say)
方法的定义#
成员方法的定义格式为:
def 函数名(self)
class Person:
# 定义成员方法sayHello
def sayHello(self):
print('hello')
# 定义成员方法run
def run(self):
print('跑')
# 创建对象
p = Person()
# 调用成员方法
p.sayHello()
注意:
成员方法有都有参数self,调用的时候不需要传递self
成员属性#
成员属性的定义需要在__init__方法下定义
格式:
def init(self):
self.属性 = 属性值
class Person:
def __init__(self,name,age):
# 成员属性
self.name = name
self.age = age
# 创建对象
p = Person('张三',30)
# 访问成员属性
print(p.name)
print(p.age)