第三天 函数 三元运算 lambda表达式 内置函数 文件操作
面向过程:
直接一行一行写代码,遇到重复的内容复制黏贴。
不利于代码阅读
代码没有复用
面向对象
将代码块定义为函数,以后直接调用函数
增强了复用性
函数的定义方法
def 函数名(传递参数):
函数体
return
1、def关键字,创建函数
2、函数名
3、():
4、 函数体
5、返回值return
函数必须先定义,之后调用。不能反过来
在执行函数体的过程中,一旦执行到return,则会立即退出函数,return之后的语句将不会被执行
当定义一个函数后,执行的时候会按照函数体进行执行,并且可以将函数体的return赋值给变量
def f1():
函数体
return 111
r = f1()
print(r) 会显示111
但是如果函数体中没有写return,python会自动给函数体返回一个默认值就是None
在执行函数的时候使用
try:
函数体
expect:
return False
else:
return True
会判断函数体的执行结果,如果遇到错误就会执行expect里的内容,否则会执行else,返回值可以自定义
函数的参数
形式参数 在定义函数时,为了能够让调用时可以输入参数而设计的参数
实际参数 在调用函数时传递的参数
def f1(形式参数)
函数体
r = f1(实际参数)
调用时传递的实际参数数量需要与定义时定义的形式参数数量一致,形式参数可以在同一个函数中定义多个,实际参数的传递顺序也需要遵循形式参数的顺序
集中传递参数的方式
函数有四类类参数
1、普通参数,按顺序复制
2、默认参数,在定义函数时定义,但是在定义时python要求默认参数必须放在形式参数列表的最后
默认参数 在定义形式参数时可以定义默认参数
def f2(xx,yy,zz="ok")
其中zz就是默认参数,在调用这个函数的时候,可以传递三个参数也可以仅传递2个参数,当三个参数时zz等于第三个参数,当两个参数时zz等于默认值"ok"
3、指定参数,在调用函数时指定赋值参数的名字
指定参数必须在调用函数时放到最后,但是不允许重复赋值给同一个参数
指定参数,默认情况下传递参数的顺序是要严格按照形式参数的顺序的,但是通过在调用时指定参数也可以改变顺序
def f3(xx,yy,zz)
f3(yy="11",zz="ok",xx="ye")
def f1(arg1,arg2,arg3)
pass
错误的指定参数
f1(arg1 = 2,arg2 =3,4) # 这是不行的
f1(4,arg2=3,arg1 =2) # 这也不行,因为相当于给arg1先赋值4 后赋值2 不允许重复赋值一个参数
f1(4,arg2=3,arg3 = 2) # 正确
4、动态参数 定义形式参数时,按正常模式应该是定义多少个参数就能使用多少个参数,但是可以使用*来转换参数,这样调用函数时传递的实际参数就不再有数量限制,而传递进的多个参数将会显示为元组的格式
def f3(*xx):
print(type(xx))
for x in xx:
print("x= %s " % x)
f3("aa","bb",33,44)
结果
<class 'tuple'>
x=aa
x=bb
x=33
x=44
传递的多个参数就是一个元组
这种方式有几种情况
当传递的实际参数是一个列表,那么传递进去后,会将这个列表作为元组中的第一个元素
def f3(*xx):
print(xx)
print(type(xx))
for x in xx:
print("x= %s " % x)
li=["aa","bb",33,44]
f3(li,"xx")
结果
(['aa', 'bb', 33, 44], 'xx') # li的全部列表作为参数的第一个元素,xx作为第二个元素
<class 'tuple'> # 整个参数变为一个列表
x=['aa', 'bb', 33, 44] # 在执行for循环时值执行了列表被完整的输出了
x=xx
当传递的实际参数本身也加了*,则会将传递的列表内的元素拆出转换为元组中的元素
def f3(*xx):
print(xx)
print(type(xx))
for x in xx:
print("x=%s"%x)
li=["aa","bb",33,44]
f3(*li,"xx") # 传递的列表前有一个星号
结果
('aa', 'bb', 33, 44, 'xx')
<class 'tuple'>
x=aa
x=bb
x=33
x=44
x=xx
当传递一个带星的字符串时,这个字符串里的每一个字母也会被转化为元组的元素
def f3(*xx):
print(xx)
print(type(xx))
for x in xx:
print("x=%s"%x)
f3(*"alix")
('a', 'l', 'i', 'x')
<class 'tuple'>
x=a
x=l
x=i
x=x
当传递2个*号时,传递的参数为字典类型
def f3(**xx):
print(xx)
print(type(xx))
for x in xx:
print("x= %s " % x)
f3(kk=11,aa=22)
输出
{'aa': 22, 'kk': 11}
<class 'dict'>
x=aa
x=kk
如果传递的参数自身是一个字典,则需要将这个传递的参数前加2个星号
def f3(**xx):
print(xx)
print(type(xx))
for x in xx:
print("x=%s"%x)
ss={'aa':22,'kk':11}
f3(**ss)
{'aa': 22, 'kk': 11}
<class 'dict'>
x=aa
x=kk
5、万能参数(*args,**kwargs):在设置形式参数时,同时制定两种动态参数,这样传入的普通参数会作为函数中元组的元素,而传入的字典,则会被**的参数转换为字典
def f4(*args,**kwargs):
print(args)
print(kwargs)
f4("aa","bb","cc",kk=123,ss="bbb")
输出
('aa', 'bb', 'cc')
{'ss': 'bbb', 'kk': 123}
万能参数会自动识别不同类型的动态参数,同时因为字典还是元组都允许为空,所以即便传递的参数并未按照函数创建的全部顺序输入,仍然可以创建对应的空元组或空字典
def f4(*args,**kwargs):
print(args)
print(kwargs)
f4(kk=123,ss="bbb") # 只传递字典格式
输出
() # 元组自动被识别为空
{'kk': 123, 'ss': 'bbb'}
万能参数在设置形式参数时必须是单个星号在前,2个星号在后,也就是必须是(*args,**kwargs)
针对函数的几点补充:
1、根据解释器读取的顺序,当出现重名函数时,最后一次出现的函数将会被执行,因为之前的函数会被之后出现的函数替换加载进内存中。
def f1():
retrun a+b
def f1():
retrun a*b
a = f1(3,4)
最终的结果,相乘的函数被执行。
2、当调用函数时,传递的并不是一个复制的值,而是合格参数的地址,因此当我们传递了一个列表给函数时,函数对这个列表做的任何操作,都将直接作用于这个列表本身。
def f1(a):
a.append(99)
list = [11,22,33]
f1(list)
print(list)
最终的结果是[11,22,33,99]
3、全局变量,定义在函数外的变量可以被任何函数引用,因此称为全局变量。而定义在函数内的变量只能被本函数引用,因此称为局部变量。全局变量应该全大写,在局部变量中如果想要更新全局变量,需要使用global,但是如果全局变量是字典或列表,则只可以修改,不可以重新赋值。
修改字符串,需要用global声明变量
NAME = "LIUBO"
def f1()
global NAME
NAME = "ZHANGSAN"
f1()
print(NAME)
修改字典
li={"a":11}
def chli():
li["b"]=22
chli()
print(li)
输出
{'a': 11, 'b': 22}
修改列表
li=[11,22]
def chli():
li.append(22)
chli()
print(li)
输出
[11, 22, 22]
上面的例子,按正常来说函数中变更的变量仅在函数内有效,但是因为使用了global的方式宣告了这个是全局变量,因此后面对NAME的修改就会应用到全局变量中
三元运算,三目运算
为真的处理 if 条件 else 为假的处理
print(1)if 1==2 else print(0)
相当于
if 1 == 2:
print(1)
else:
print(0)
条件为真 打印1 ,条件为假打印0
a = 1 if 1 == 1 else 2
条件为真时 a = 1 ,条件为假时 a = 2
等价于
if 1 == 1:
a = 1
else:
a = 2
lambda表达式,对于简单的函数可以直接使用lambda表达式定义
def f1(a1,a2):
return a1+a2
上面的函数等价于
f1 = lambda a1,a2: a1+a2
def f1(a1,a2=9)
return a1+a2+100
可以写为
f1 = lambda a1,a2=9 : a1+a2+100
f1(9) #因为函数定义了默认参数,因此只需要传递一个参数即可
lambda表达式仅能使用一行定义,因此只能定义简单函数,即函数中不能在加入其它的操作,直接返回
内置函数
abs() 取绝对值
n = abs(-1)
print(n)
输出为1
all() 所有为真,才为真
在布尔函数中表示False的内容有0,None,“”,[],{}
即空的字符串,列表,字典 元祖都是False
all([11,22,33]) 这样为真
all([11,22,“”) 这样就为假了
any() 有真就是真
ascii() 自动执行对象的_repr_方法
bin() 接收一个十进制数字转为二进制
oct() 接收一个十进制数字转为八进制
hex() 接收一个十进制数字转为十六进制
bool() 返回真假
bytes()
对于UTF-8编码一个汉字占3个字节
GBK编码一个汉字2个字节
字符串转换为字节类型,bytes("要转换的字符串",encoding="所用的编码类型")
print(bytes("刘",encoding="utf-8"))
print(bytes("刘",encoding="gbk"))
str()
将字节转化为字符串
str(需要转化的字节,encoding="需要的编码类型")
print(str(b'\xe5\x88\x98',encoding="utf-8"))
open()
文件操作
1、打开文件
f = open("文件名","操作模式",encoding="编码")
在打开一个文件时,这个文件里的内容是二进制的,那么二进制转换为字符串时有一个转换动作的。
open语句会使用一个默认的编码方式来读取文件,更换编码需要在open中指定
open("text.log","r",encoding="gbk")
在操作模式中有一个b(rb,xb,wb),这样相当于我们不需要python帮我们做编码转换,那么无论是我们写还是读就都需要使用二进制的数据类型传递。
也就是操作模式没有b则是字符串类型str ,只要有b则是字节型,bytes
f=open("test.log","ab")
f.write(bytes("刘博",encoding="utf-8")) # 写操作必须要加编码
f.close()
文件内容(追加)
dial-peer voice 1 voip1
dial-peer voice 1 voip2
dial-peer voice 1 voip3
dial-peer voice 1 voip4
dial-peer voice 1 voip5
dial-peer voice 1 voip6
刘博
+符号代表操作模式可读可写,但是方式有所区别
每当open一个文件时,相当于有一个指针出现在文件中,当read()时代表文件内所有的字节都被读了一次,这时指针也就随之指向到文件的最后。
可以通过seek(位置)方法来指定指针的位置。无论是使用b还是不带b的方式读取,seek都是按照字节来制定位置,如果存在汉字,一个汉字在utf8中是3个字节,如果文件只有一个汉字,但是seek(1)这样指针实际上是指到了这个汉字的第一个字节的后面。
在写入一个内容的时候,python会默认从指针的位置向后替换 原有的字符
f=open("test.log","r+")
f.seek(10) #将指针指向第10个位置
f.write("ssss")
f.close()
结果
dial-peer sssse 1 voip1 #可以看到从第十个字符开始原来的voice前4个字母被替换为s了
dial-peer voice 1 voip2
dial-peer voice 1 voip3
dial-peer voice 1 voip4
dial-peer voice 1 voip5
dial-peer voice 1 voip6
刘博
获取当前指针的位置tell(),tell方法指定的位置永远是字节
f=open("test.log","r+")
f.seek(10)
a=f.tell()
f.close()
print(a)
打印
10
r+,a+,w+三种都是可读可写,但是只有r+可以指定指定指针的位置写入,a+是追加无论怎么指定,写入的都只能从最后追加,w+则会清空源文件
因此写入方式中r+使用的最广泛
操作模式:
r |
只读 |
w |
只写(先清空源文件,后写入) |
x |
python3.0新增:如果文件存在时则报错,如果不存在创建并写内容 |
a |
追加 |
r+ |
可读可写,最常用 |
a+ |
可读可写,从最后写 |
w+ |
可读可写,但是先清空源文件 |
2、操作文件
通过源代码查看功能
read(),如果无参数,则读全部,如果有参数,打开方式如果有b按字节读取,无b按字符读取。
seek(),按字节指定指针位置
tell(),按字节获取当前指针位置
write(),写数据,如果打开方式中有b按字节,无b按字符写
close()
fileno() 文件描述符,即文件的数字表达方式
flush() 强刷,将内容强刷到硬盘上,当我们打开了一个文件,写入一个内容,之后做了一个操作暂停在这里(比如input要求用户输入,但用户没有输入)此时文件没有关闭。默认情况下这个内容是不会写到文件里的。此时可以通过flush方法在文件关闭前强制将内容写到文件中。
readable() 判断是否可读
seekable() 判断是否可以移动指针
readline() 仅读取一行,实际是执行完这句后,指针指向第二行开始,所以在此执行就会读取第二行
writeable() 判断是否可写
truncate() 会将指针后面的内容全部清空
for循环open之后的文件对象,循环每一行
f = open("test.log","r")
for line in f:
print(line)
3、关闭文件
f.close()
使用with的文件操作
with open("文件名") as f:
pass
上面的with代码执行完,文件自动关闭,不需要特意写close
python 2.7之后with支持打开多个文件
with open("1.log","r",encoding="utf-8") as f1, open("2.log","w",encoding="utf-8") as f2:
time = 0
for line in f1:
time += 1
if time <=10:
f2.write(line)
else:
break
上面的代码使用with,只读打开1.log,只写打开2.log,然后将1.log中前10行数据写入2.log中
上面说打在python中写入数据是从指针位置开始替换后面的,那么当我们要修改文件中不等长的数据(例如将alex替换为st)就会破坏原有的数据。
而open读取的数据默认是字符串的类型,因此我们可以使用字符串的操作。str.replace("源字符串","替换字符串")的方式替换。
逐行处理就是
with open("1.log","r",encoding="utf-8") as f1, open("2.log","w",encoding="utf-8") as f2:
for line in f1:
new_str = line.replace("alex","st")
f2.write(new_str)
第三天 函数 三元运算 lambda表达式 内置函数 文件操作的更多相关文章
- 三元运算+lambda表达式
#三元运算,三目运算,if else简写 if 1 == 1: name = "liangml" else: name = "NB" #如果 1==1 成立,n ...
- 学习Python函数笔记之二(内置函数)
---恢复内容开始--- 1.内置函数:取绝对值函数abs() 2.内置函数:取最大值max(),取最小值min() 3.内置函数:len()是获取序列的长度 4.内置函数:divmod(x,y),返 ...
- Python函数04/生成器/推导式/内置函数
Python函数04/生成器/推导式/内置函数 目录 Python函数04/生成器/推导式/内置函数 内容大纲 1.生成器 2.推导式 3.内置函数(一) 4.今日总结 5.今日练习 内容大纲 1.生 ...
- python---基础知识回顾(一)(引用计数,深浅拷贝,列表推导式,lambda表达式,命名空间,函数参数逆收集,内置函数,hasattr...)
一:列表和元组(引用计数了解,深浅拷贝了解) 序列:序列是一种数据结构,对其中的元素按顺序进行了编号(从0开始).典型的序列包括了列表,字符串,和元组 列表是可变的(可以进行修改),而元组和字符串是不 ...
- Day05:装饰器,三元表达式,函数的递归,匿名/内置函数,迭代器,模块,开发目录
上节课复习:1.函数的对象 函数可以被当作数据取处理2.函数嵌套 嵌套调用:在调用一个函数时,函数体代码又调用了其他函数 嵌套定义:在一个函数内部又定义了另一个函数 def foo( ...
- set、def、lambda、内置函数、文件操作
set : 无序,不重复,可以嵌套 .add (添加元素) .update(接收可迭代对象)---等于批量 添加 .diffrents()两个集合不同差 .sysmmetric difference( ...
- python 全栈开发,Day14(列表推导式,生成器表达式,内置函数)
一.列表生成式 生成1-100的列表 li = [] for i in range(1,101): li.append(i) print(li) 执行输出: [1,2,3...] 生成python1期 ...
- python 基础篇 14 程程器表达式 内置函数
昨日内容回顾 可迭代对象: 内部含有__iter__方法的就是可迭代对象. 可迭代对象不能取值,因为内部不含有__next__方法. 可迭代对象 ---> ...
- python函数(6):内置函数和匿名函数
我们学了这么多关于函数的知识基本都是自己定义自己使用,那么我们之前用的一些函数并不是我们自己定义的比如说print(),len(),type()等等,它们是哪来的呢? 一.内置函数 由python内部 ...
随机推荐
- 用scikit-learn研究局部线性嵌入(LLE)
在局部线性嵌入(LLE)原理总结中,我们对流形学习中的局部线性嵌入(LLE)算法做了原理总结.这里我们就对scikit-learn中流形学习的一些算法做一个介绍,并着重对其中LLE算法的使用方法做一个 ...
- 关于在freemarker模板中遍历数据模型List<JavaBean>的经验
本文采用简单的servlet作为后台处理数据的工具,前台使用freemarker的ftl模板作为输出工具,简单说明怎样将封装有实体类对象的List集合注入到ftl模板中并且成功的在遍历显示出来,之前在 ...
- for循环和while循环
for循环和while循环 --道心 for循环 name1_list=['daoxin','wuxin','zhixin']for ele in name1_list: #找到"wuxin ...
- 1 Selenium打开浏览器
[环境] Selenium3.0.1+Python3.6+unittest win7+IE10 1.打开FireFox浏览器 import unittest from selenium import ...
- 数据持久层框架iBatis, Hibernate 与 JPA 比较
在本文中我们介绍并比较两种最流行的开源持久框架:iBATIS和Hibernate,我们还会讨论到Java Persistence API(JPA).我们介绍每种解决方案并讨论其所规定的品质,以及在广泛 ...
- Python datetime模块的datetime类
datetime模块定义了下面这几个类: datetime.date:表示日期的类.常用的属性有year, month, day. datetime.time:表示时间的类.常用的属性有hour, m ...
- Kafka集群搭建
1.zookeeper搭建 Kafka集群依赖zookeeper,需要提前搭建好zookeeper zookeeper快速搭建推荐地址:http://nileader.blog.51cto.com/1 ...
- yarn的调度器
三种调度器 1.FIFO Scheduler 把应用按提交的顺序排成一个队列,这是一个先进先出队列,在进行资源分配的时候,先给队列中最头上的应用进行分配资源,等最前面的应用需求满足后再给下一个分配,以 ...
- JSONP 的工作原理是什么?
利用<script>标签没有跨域限制的"漏洞"来达到与第三方通讯的目的. 当需要通讯时,本站脚本创建一个<script>元素,地址指向第三方的API网址,形 ...
- CODE[VS]-寻找子串位置-字符串处理-天梯青铜
题目描述 Description 给出字符串a和字符串b,保证b是a的一个子串,请你输出b在a中第一次出现的位置. 输入描述 Input Description 仅一行包含两个字符串a和b 输出描述 ...