python笔记(四)文件操作和函数

一,文件操作基本流程。

打开文件方法一

文件句柄 = open(‘文件路径’,‘模式’, '字符编码')

1 #1. 打开文件open,得到文件句柄并赋值给一个变量
2 f=open('a.txt','r',encoding='utf-8') #默认打开模式就为r
3 
4 #2. 通过句柄对文件进行操作
5 data=f.read()
6 
7 #3. 注意关闭文件,防止占用资源
8 f.close()

打开文件方法二

# 单个文件操作,as后为变量名称
with open("一首诗",mode="r",encoding="UTF-8") as f:
     pass
# 可多文件进行操作
with open("一首诗", mode="r", encoding="UTF-8") as f,open("一首词", mode="w", encoding="UTF-8"):
    pass

 encoding,用字符编码,可防止打开的文件乱码!

 

二、文件的打开模式

#1. 打开文件的模式有(默认为文本模式):
r ,只读模式【默认模式,文件必须存在,不存在则抛出异常】
w,只写模式【不可读;不存在则创建;存在则清空内容】
a, 只追加写模式【不可读;不存在则创建;存在则只追加内容】

#2. 对于非文本文件,我们只能使用b模式,"b"表示以字节的方式操作(而所有文件也都是以字节的形式存储的,使用这种模式无需考虑文本文件的字符编码、图片文件的jgp格式、视频文件的avi格式)
rb 
wb
ab
注:以b方式打开时,读取到的内容是字节类型,写入时也需要提供字节类型,不能指定编码

#3,‘+’模式(就是增加了一个功能)
r+, 读写【可读,可写】
w+,写读【可写,可读】
a+, 写读【可写,可读】

#4,以bytes类型操作的读写,写读,写读模式
r+b, 读写【可读,可写】
w+b,写读【可写,可读】
a+b, 写读【可写,可读】

 

三,文件操作方法。

常用的操作方法

read(3):

  1. 文件打开方式为文本模式时,代表读取3个字符

  2. 文件打开方式为b模式时,代表读取3个字节

其余的文件内光标移动都是以字节为单位的如:seek,tell,truncate

注意:

  1. seek有三种移动方式0,1,2,其中1和2必须在b模式下进行,但无论哪种模式,都是以bytes为单位移动的

  2. truncate是截断文件,所以文件的打开方式必须可写,但是不能用w或w+等方式打开,因为那样直接清空文件了,所以truncate要在r+或a或a+等模式下测试效果

 1 f = open("一首诗",mode="r",encoding="UTF-8")
 2 b = f.read()
 3 print(b)  # 人生若只如初见,何事悲风秋画扇
 4 f.seek(3) # 光标移动都是以字节为单位
 5 b = f.read()
 6 print(b)  # 生若只如初见,何事悲风秋画扇
 7 print(f.tell()) # 43 光标位置
 8 print(f.readline())  #一行一样读
 9 print(f.readlines())  # 一次性读取整个文件,自动将文件内容分析成一个行的列表
10 f.close()

 

四、文件的修改

1 f = open("一首诗",mode="w",encoding="UTF-8")
2 f.write("****")  # 只写模式【不可读;不存在则创建;存在则清空内容】

 

1 with open("小美女",encoding='UTF-8') as a ,open('小美女_the',"w",encoding="UTF-8") as a1 :
2     for i in a:
3         if "小红" in i:
4             i = i.replace("小红","大白")  # 小红修改为大白
5         a1.write(i)  # 写入 a1
6 import os
7 os.remove("小美女")  # 删除文件
8 os.rename('小美女_the',"小美女")  # 从新命名文件

 

 

 

五、函数

5.1函数的表现形式

def 函数名(参数1,参数2,xx)
    '''注释
  参数表示的意义
  return:xxx
  ''' 函数体 return 返回的值 #函数名要反映其意义,函数即“变量”,“变量”必须先定义后引用。未定义而直接引用函数,就相当于在引用一个不存在的变量名!

5.2函数的返回值(return)

没有返回值

 

 1 #没有返回值,不写return,或者写return None
 2 def mylen():
 3     """计算s1的长度"""
 4     s1 = "hello world"
 5     length = 0
 6     for i in s1:
 7         length = length+1
 8     print(length)
 9 # 函数调用
10 str_len = mylen()
11 # 因为没有返回值,此时的str_len为None
12 print('str_len : %s' % str_len)

 

返回一个值

 

 

#返回一个值只需在return后面写上要返回的内容即可
def mylen():
    """计算s1的长度"""
    s1 = "hello world"
    length = 0
    for i in s1:
        length = length+1
    return length

#函数调用
str_len = mylen()
print('str_len : %s'%str_len)

 

 

返回多个值

 

 1 def ret_demo2():
 2     ''' 返回多个值 '''
 3     return 1,['a','b'],3,4
 4 #返回多个值,用一个变量接收
 5 ret2 = ret_demo2()
 6 print(ret2)
 7 '''返回多个值,用多个变量接收
 8 因为python中把用逗号分割的多个值就认为是一个元祖
 9 所以可以用多个值接收返回值返回几个值,就用几个变量接收'''
10 a,b,c,d = ret_demo2()
11 print(a,b,c,d)

 

5.3函数的参数

实参形参和传参
 1 #函数定义,s1为形参
 2 def mylen(s1):
 3     """计算s1的长度"""
 4     length = 0
 5     for i in s1:
 6         length = length + 1
 7     return length
 8 # 函数调用,s2为实参
 9 s2 = "hello python"
10 str_len = mylen(s2)
11 print('str_len : %s' % str_len)
12 #整个过程称为传参
传递多个参数
def mymax(x,y): #参数可以传递多个,多个参数之间用逗号分割
    the_max = x if x > y else y
    return the_max

ma = mymax(10,20)
print(ma)
位置参数

正确用法

  一:位置参数必须在关键字参数的前面

  二:对于一个形参只能赋值一次

 1 def mymax(x, y):
 2     # 此时x=10,y=20
 3     the_max = x if x > y else y
 4     return the_max
 5 ma = mymax(10, 20)  # 按照位置传参,
 6 print(ma)
 7 ma1 = mymax(x=10, y=20)  # 按照关键字传值
 8 print(ma1)
 9 ma2 = mymax(10, y=20)  # 位置、关键字形式混着用
10 print(ma2) 
11 ma3 = mymax()
12 print(ma3)  # 报错,位置参数必须穿值
默认参数,将变化比较小的值设置成默认参数
1 def stu_info(name, sex=""):
2     """打印名字,因为大多数都是男生
3     所以可以将sex设置为默认参数
4     """
5     print(name, sex)
6 stu_info('小明')  # 结果为:小明 男 sex为默认为男
7 stu_info('小红', '')  # 结果为:小红 女
8 stu_info('小红', sex='')  # 结果为:小红 女

 

    参数陷阱:默认参数是一个可变数据类型

1 def defult_param(a,l = []):
2     l.append(a)
3     print(l)
4 
5 defult_param('小明')
6 defult_param('小红')
动态参数

按位置传值多余的参数都由args统一接收,保存成一个元组的形式

1 def mysum(*args):
2     the_sum = 0
3     for i in args:
4         the_sum+=i
5     return the_sum
6 
7 the_sum = mysum(1,2,3,4)
8 print(the_sum)
9 #args求和函数应用

按位置传值多余的参数都由args统一接收,保存成一个字典的形式

1 def stu_info(**kwargs):
2     print(kwargs)
3     print(kwargs['name'],kwargs['sex'])
4 
5 stu_info(name = '小明',sex = '')

 参数排放顺序:位置参数-->*args-->默认参数-->**kwargs

 

六、命名空间和作用域

6.1 命名空间

命名空间分为三种:

    全局命名空间------全局命名空间为:顾名思义,除def函数外的变量名称

    局部命名空间------局部命名空间为:def函数内部的变量名称

    内置命名空间------内置命名空间为:python解释器中内置的函数名称

三种命名空间之间的加载顺序:

    加载顺序:内置命名空间(程序运行前加载)->>>>全局命名空间(程序运行中:从上到下加载)->>>>全局命名空间(程序运行中:调用时才加载)

三种命名空间之间的取值顺序:

在局部调用:局部命名空间->>>>全局命名空间->>>>内置命名空间

在全局调用:全局命名空间->>>>内置命名空间

6.2作用域

作用域就是作用范围,按照生效范围可以分为全局作用域和局部作用域。

局作用域:包含内置名称空间、全局名称空间,在整个文件的任意位置都能被引用、全局有效

局部作用域:局部名称空间,只能在局部范围生效

global关键字

 

1 a = 10
2 def func():
3     global a  # 引用全局的变量a
4     a = 20
5 
6 print(a)  # 10
7 func()
8 print(a)  # 20

 

globals() 函数会以字典类型返回当前位置的全部全局变量。

1 a='runoob'
2 print(globals()) 
3 
4 '''globals 函数返回一个全局变量的字典,包括所有导入的变量。
5 {'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', '__doc__': None, 'a': 'runoob', '__package__': None}'''

locals() 函数会以字典类型返回当前位置的全部局部变量。

1 def runoob(arg):    # 两个局部变量:arg、z
2     z = 1
3     print (locals())
4 
5 runoob(4)  # {'z': 1, 'arg': 4}, 返回一个名字/值对的字典

 

七、函数的嵌套

7.1函数的嵌套调用

def max2(x,y):
    m  = x if x>y else y
    return m

def max4(a,b,c,d):
    res1 = max2(a,b)
    res2 = max2(res1,c)
    res3 = max2(res2,d)
    return res3
print(max4(1,5,6,8,))  # 8

7.2函数的嵌套定义

 1 def f1():
 2     def f2():
 3         def f3():
 4             print("in f3")
 5         print("in f2")
 6         f3()
 7     print("in f1")
 8     f2()
 9 f1() 
10 '''
11 输出为
12 in f1
13 in f2
14 in f3
15 '''

 

八、函数的作用域链

nonlocal关键字

1.外部必须有这个变量
2.在内部函数声明nonlocal变量之前不能再出现同名变量
3.内部修改这个变量如果想在外部有这个变量的第一层函数中生效

1 def f1():
2     a = 1
3     def f2():
4         nonlocal a
5         a = 2
6     f2()
7     print('a in f1 : ',a)
8 
9 f1()  # a in f1 :  2

 

九、函数名称的本质

函数名本质上就是函数的内存地址

1.可以被引用

 

1 def func():
2     print('in func')
3 
4 f = func
5 print(f)

2.可以被当作容器类型的元素

 1 def f1():
 2     print('f1')
 3 def f2():
 4     print('f2')
 5 def f3():
 6     print('f3')
 7 l = [f1,f2,f3]
 8 d = {'f1':f1,'f2':f2,'f3':f3}
 9 #调用
10 l[0]()
11 d['f2']()

3.可以当作函数的参数和返回值,当普通变量用

第一类对象(first-class object)指

1.可在运行期创建

2.可用作函数参数或返回值

3.可存入变量的实

 

十、闭包

1 def func():
2     name = 'eva'
3     def inner():
4         print(name)
5     return inner
6 
7 f = func()
8 f()

闭包函数:

内部函数包含对外部作用域而非全剧作用域名字的引用,该内部函数称为闭包函数
#函数内部定义的函数称为内部函数

判断闭包函数的方法__closure__

 1 #输出的__closure__有cell元素 :是闭包函数
 2 def func():
 3     name = 'eva'
 4     def inner():
 5         print(name)
 6     print(inner.__closure__)
 7     return inner
 8 
 9 f = func()
10 f()
11 
12 #输出的__closure__为None :不是闭包函数
13 name = 'egon'
14 def func2():
15     def inner():
16         print(name)
17     print(inner.__closure__)
18     return inner
19 
20 f2 = func2()
21 f2()

闭包嵌套

 1 def wrapper():
 2     money = 1000
 3     def func():
 4         name = 'eva'
 5         def inner():
 6             print(name,money)
 7         return inner
 8     return func
 9 
10 f = wrapper()
11 i = f()
12 i()

 

小结

命名空间:

  一共有三种命名空间从大范围到小范围的顺序:内置命名空间、全局命名空间、局部命名空间

作用域(包括函数的作用域链):

小范围的可以用大范围的
但是大范围的不能用小范围的
范围从大到小(图)

在小范围内,如果要用一个变量,是当前这个小范围有的,就用自己的
如果在小范围内没有,就用上一级的,上一级没有就用上上一级的,以此类推。
如果都没有,报错

函数的嵌套:

  嵌套调用

  嵌套定义:定义在内部的函数无法直接在全局被调用

函数名的本质:

  就是一个变量,保存了函数所在的内存地址

闭包:

  内部函数包含对外部作用域而非全剧作用域名字的引用,该内部函数称为闭包函数

 

posted @ 2018-07-26 23:26  要死醉生梦死  阅读(197)  评论(0编辑  收藏  举报
# 一段js特效的代码 # 使用方法:粘贴到页脚代码