首页 > 其他 > 详细

第三天 函数 三元运算 lambda表达式 内置函数 文件操作

时间:2017-01-12 13:07:47      阅读:315      评论:0      收藏:0      [点我收藏+]

  面向过程:

 

直接一行一行写代码,遇到重复的内容复制黏贴。

 

不利于代码阅读

代码没有复用

 

面向对象

 

将代码块定义为函数,以后直接调用函数

 

增强了复用性

 

 

函数的定义方法

 

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表达式 内置函数 文件操作

原文:http://www.cnblogs.com/LB-BK/p/6275672.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!