day3-文件读取、函数、字符编码转换、全局变量与局部变量

1.函数

==============第一个函数=================

def fun1():
    # this is my first function
    print('Hello Function!')
    return 0

---》》第一个函数,def定义函数,无参数,返回值为0,打印‘Hello Function’

==============第一个过程=================

def proce1():
    # this is my first procedure
    print('Hello Procedure')

---》》函数和过程的区别是,过程没有返回值。。。函数也可以没有返回值啊?擦!咋区别?

==============函数的返回值=================

'''
函数返回值:
1.无return,返回none
2.return一个值,返回object(值本身,python所有值都可以看作一个对象)
3.return多个值,返回一个tuple

为什么要有返回值:
我想要整个函数执行的结果,后面的程序需要根据这个执行结果进行不同的操作
'''
# 无返回值
def test_none():
    print('this is test_none'.ljust(50,'-'))

#返回值为0
def test_num():
    print('this is test_num'.ljust(50,'-'))
    return 0

#返回一个tuple
def test_tuple():
    print('this is test_tuple'.ljust(50,'-'))
    return 3,'champions',[1,'中金所','随便'],{'name':'yang','age':'secret'}

#此为高阶函数,返回要给函数
def test_high():
    print('this is test_high'.ljust(50,'-'))
    return test_num #返回test_num函数的内存地址

print(test_none())
print(test_num())
print(test_tuple())
print(test_high())

==============局部变量与全局变量=================

school='天庭' #全局变量,全局生效
def change_name(name):
    print('Before change:',name)
    school='花果山' #局部变量,函数内生效
    print('Local variable:',school)
    name='齐天大圣' #局部变量,调用函数时,实现改名字功能
    print('After change:',name)

name='孙悟空' #全局变量
change_name(name)
print('Global variable:',school)

 

=============需要传参的函数=================

def func_arg(x,y):
    print(x,y)

#func_arg(1,2)
#func_arg(1)  #func_arg() missing 1 required positional argument: 'y'
# func_arg(1,2,3) #func_arg() takes 2 positional arguments but 3 were given

'''
x=1 #此x为实参,换成a=1,会不会直观点,哈哈
y=2 #次y为实参,换成b=2,会不会直观点,哈哈
func_arg(x=x,y=y)
'''

#func_arg(1,2) #位置参数调用,与形参位置一一对应
#func_arg(y=1,x=2) # 关键字参数调用,与形参位置无关

#func_arg(x=1,2) #不可以,positional argument follows keyword argument
#func_arg(1,y=2) #可以,关键字参数必须在最后
#func_arg(1,x=2) #不可以,x有多个值,test1() got multiple values for argument 'x'

'''
def test1(x,y,z):#形参
    print(x)
    print(y)
    print(z)

#test1(1,y=2,3) #不可以,positional argument follows keyword argument
test1(1,2,z=3) #可以
test1(3,z=6,y=9) #可以
'''

 

===============需要传参的函数,参数带默认值================

'''
default argument特点:
1.调用函数的时候,默认参数可不传

应用场合:
1.默认安装
2.数据库链接字符串

'''
def test1(x,y=2):
    print(x)
    print(y)
#test1(1)
#test1(1,y=3)
#test1(1,3)

 

===============一个函数,若参数数目不固定,则使用参数组================

 

'''
针对形参数量不固定,下面隆重介绍:参数组
'''
# def test1(*args): #接收N个位置参数,转换成元组的方式,不能接受关键字参数
#     print(args) #封装为元组
#     #print(*args) #不封装
#
# test1(1,2,3,4,5) #多个实参放到一个元组里
# test1([7,8,9,0]) #列表作为元组的一个元素
# test1(*[7,8,9,0]) #同多个实参放到一个元组里
# test1({'name':'weixiaobao','age':16},1,2) #字典作为元组的一个元素

# def test2(x,*args):
#     print(x)
#     print(args) #参数封装成元组输出
#
# test2(1,2,3,4,5,6)

#字典
#把N个关键字参数转换成字典的方式
# def test3(**kwargs): #接受关键字参数,转换成字典方式
#     print(kwargs)
#     print(kwargs['name'])
#     print(kwargs['age'])
#     print(kwargs['sex'])
# test3(name='bajie',age=500,sex='f')
# test3(**{'name':'bajie','age':500,'sex':'f'})

#综合使用
# def test4(organization,**kwargs):
#     print(organization)
#     print(kwargs)

#test4('tianting',name='neza',age=300,sex='x') #完美传参
#test4('diyu') #最懒传参,字典为空
#test4('renjian',6) #错误传参,test4() takes 1 positional argument but 2 were given

#终极综合使用
# def test5(organization,position,*args,**kwargs):  #参数组一定要往后放
#     print(organization)
#     print(position)
#     print(args)
#     print(kwargs)
#test5('tianting','33tian',1,2,3,name='change',age=18) #完美调用
#test5('renjian','saodi') #最懒调用,元组和字典都为空

#一个函数中引用其他函数
# def test6(organization,position=33,*args,**kwargs):
#     print(organization)
#     print(position)
#     print(args)
#     print(kwargs)
#     logger('test6')
# def logger(source):
#     print('from %s',source)
# test6('diyu')

#接下来给你一个错误示例
# def test6(organization,position=33,*args,**kwargs):
#     print(organization)
#     print(position)
#     print(args)
#     print(kwargs)
#     logger('test6')
# test6('diyu') #name 'logger' is not defined,从上到下执行,此时logger还未定义
# def logger(source):
#     print('from %s',source)


#最最最使用传参方式,随你咋搞都不报错
def test7(*args,**kwargs):
    print(args)
    print(kwargs)
test7()
test7(1)
test7(name='wukong')
test7(1,name='wukong')

 

===============高阶函数,初识================ 

#higher order function
# ads 内置函数
def add(a,b,f):
    print(a)
    print(b)
    return f(a)+f(b)
res=add(2,3,abs)
print(res)

 

===============递归函数================

'''
recursion,递归函数
1.必须要有个明确的结束条件
2.每次进入更深一层时,问题规模相对上次都应有所减少
3.递归效率不高,递归层次过多会导致栈溢出
'''
def recur_calc(n):
    print(n)
    if int(n/2)>0:
        return recur_calc(n/2)
    print('--->>',n)
recur_calc(10)

 

===============函数尾声================

'''
函数优点:
1.代码重用
2.程序容易扩展
3.代码一致性
'''
import time
def addlog():
    time_format='%Y-%m-%d %X'
    time_current=time.strftime(time_format)
    with open('log','a+',encoding='utf-8') as f:
        f.write('%s this is used add log...\n' %time_current)
def test1():
    print('this is test1')
    addlog()

def test2():
    print('this is test2')
    addlog()


test1()
test2()

 

 

 

 

 

  

 

 

2.集合(set)

list_1=[1,3,5,7,9]
list_1=set(list_1)
list_2=[2,4,6,8,9,0]
list_2=set(list_2)

print(list_1,list_2)

#交集
print('交集intersection方法:',list_1.intersection(list_2))
print('交集\'&\'运算符:',list_1 & list_2)

#并集
print('并集union方法:',list_1.union(list_2))
print('并集\'|\'运算符:',list_1 | list_2)

#差集
print('差集difference方法1-2:',list_1.difference(list_2)) #in list_1 but not in list_2
print('差集difference方法2-1:',list_2.difference(list_1)) #in list_2 but not in list_1
print('差集\'-\'运算符1-2:',list_1-list_2)

#子集
list_3=set([1,3,5])
print('list_3是list_1的子集:',list_3.issubset(list_1)) #list_3是list_1子集
print('list_1是list_3的父集:',list_1.issuperset(list_3))

#对称差集
print('对称差集symmetric方法:',list_1.symmetric_difference(list_2)) #去掉交集元素
print('对称差集\'^\'运算符:',list_1 ^ list_2)

print('----------------------')
list_4=set([5,6,7,8])
print(list_3.isdisjoint(list_4)) #return True if tow sets have a null intersection.

# 添加一项
list_1.add('222')
print(list_1)

# 添加多项
list_1.update([555,666,777])
print(list_1)

# 删除一项
list_1.remove('222')
print(list_1)

# set的长度
print(len(list_1))

# 判断元素是否在集合中
if 666 in list_1:
    print('666 is a element of set!')
if 222 not in list_1:
    print('222 is not a element of set!')

# 浅copy
list_1_copy=list_1.copy()
print('list_1的浅copy:',list_1_copy)

 

3.文件操作

==============先来个Example,登录=================

'''
通过读取文件的方式登陆,文件格式如下:
sunwukong,swk123
zhubajie,zbj123
jiabaoyu,jby123
'''
usernames=[]
passwords=[]
fobj=open('login.txt','r')
username=input('username:')
password=input('password:')
while True:
    lines=fobj.readline().strip()
    if not lines:
        break
    t_names,t_pwds=[str(s) for s in lines.split(',')]
    usernames.append(t_names)
    passwords.append(t_pwds)

if username in usernames:
    pwd_index=usernames.index(username)
    if password==passwords[pwd_index]:
        print('welcome login...')
    else:
        print('Invalid password!')
else:
    print('User non-exsitent!')

==============步步推进,先来个简单的文件opration吧=================

1. Somehow, it seems the love I knew was always the most destructive kind
2. 不知为何,我经历的爱情总是最具毁灭性的的那种
3. Yesterday when I was young
4. 昨日当Alex年少轻狂
5. The taste of life was sweet
6. 生命的滋味是甜的
7. As rain upon my tongue
8. 就如舌尖上的雨露
9. I teased at life as if it were a foolish game
10. 我戏弄生命 视其为愚蠢的游戏

---》》以上为文件的内容

f=open('song','r',encoding='utf-8') #打开文件,以只读的方式,采用‘utf-8’编码(操作系统默认gbk)
first_line=f.readline() #读取第一行
print(first_line)
second_line=f.readline() #读取第二行
print(second_line)
third_line=f.readline() #读取第三行
print(third_line)
print('我是分割线'.center(50,'-'))
data=f.read() #读取剩下的全部,文件大时不要用
print(data)
f.close() #关闭文件

---》》试试f.read()后,再使用f.read()或者f.readlines(),打印出结果,看看会发生什么。

==============向前走,先来看9种操作模式的前3式(r,w,a)=================

 

# file opr
# r:只读
# w: 只写
# a: 追加
# with open('song','r',encoding='utf-8') as f:
#     line=f.readline() #读取一行
#     data=f.read() #读取剩下的全部
#     lines=f.readlines() #啥也都不到,只剩一个空列表
#     print(line)
#     print(data)
#     print(lines)

# with open('song','w',encoding='utf-8') as f:
#     str='自在飞花轻似梦,无边丝雨细如愁'
#     f.write(str) #删除文件原有内容,写入str内容,慎重使用!!!

# with open('song','a',encoding='utf-8') as f:
#     str='\n自在飞花轻似梦,无边丝雨细如愁'
#     f.write(str) #在原有内容末尾添加

==============继续走,再来看9种操作模式的中间3式(r+,w+,a+)=================

# file opr
# r+ 可读、可写,文件若不存在,则报IOError
# w+ 写读,首先创建一个新文件,再在新文件中写
# a+ 追加读写
# with open('song','r+',encoding='utf-8') as f:
#     ############ read ############
#     # line=f.readline()
#     # print(line)
#     # data=f.read()
#     # print(data)
#     # lines=f.readlines()
#     # print(lines)
#     ############ write ############
#     str = '噫嘘唏!蜀道难,难于上青天!'
#     f.write(str) #写入时,使用str从头开始替换原文件内容

# with open('song','w+',encoding='utf-8') as f: #写读,如果文件不存在就创建一个
#     str='自在飞花轻似梦,无边丝雨细如愁'
#     f.write(str) #清空原有内容,然后写入str
#     data=f.read() #明明有内容,为啥都出来为空?有毛用!!!
#     print(data)

# with open('song','a+',encoding='utf-8') as f: #a+w 可写,可追加,文件不存在就创建
#     data=f.read()
#     print(data) #读不出来,不可读?
#     str = '\n自在飞花轻似梦,无边丝雨细如愁'
#     f.write(str) #追加可以

==============最后走,再来看9种操作模式的最后3式(rb,wb,ab)=================

# file opr
# rb:读二进制文件
# wb:写二进制文件
# ab: 追加二进制文件
# with open('song','rb') as f: #二进制读
#     line=f.readline()
#     print(line) #打印出的结果以b打头,代表bytes类型
# with open('song','wb') as f: #二进制写
#     binary='Hello Binary'.encode() #字符串转换为二进制
#     f.write(binary)
with open('song','ab') as f: #二进制追加
    # line=f.readline() #好吧,次模式不支持和read,报“io.UnsupportedOperation: read”
    # print(line)
    binary='自在飞花轻似梦,无边丝雨细如愁'.encode()
    f.write(binary) #追加到源文件内容末尾

  

==============以为只有9中,你错了骚年,再来看(rb+,wb+,ab+)=================

pass

==============模式汇总=================

'''
模式    描述
r    以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。
rb   以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。
r+   打开一个文件用于读写。文件指针将会放在文件的开头。
rb+  以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。
w    打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
wb   以二进制格式打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
w+   打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
wb+  以二进制格式打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
a    打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
ab   以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
a+   打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。
ab+  以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。
'''

==============文件的循环读取================= 

# 循环读取
# 第一种简单循环
# with open('song','r',encoding='utf-8') as f:
#     for line in range(5):
#         print(f.readline())

# 转换为列表,使用readlines方法
# with open('song','r',encoding='utf-8') as f:
#     for line in f.readlines(): #readlines 列表,每行为一个列表元素,相当于循环读取一个列表
#         print(line.strip())

# 可以表示每行的序号,以0开始
# with open('song','r',encoding='utf-8') as f:
#     data=f.readlines()
#     for index,line in enumerate(data):
#         # print(index,line.strip())
#         if index==5:
#             print('我是分割线'.center(50,'-'))
#         print(line.strip())

# hign bg 效率最高,f变为迭代器
# with open('song','r',encoding='utf-8') as f:
#     count = 0
#     for line in f:
#         if count == 5:
#             print('我是分割线'.center(50, '-'))
#             count += 1
#             #break
#             continue
#         print(line.strip())
#         count += 1

==============文件的修改================= 

#使用此方式无法修改
# with open('song','r+',encoding='utf-8') as f:
#     if f.readable() and f.writable():
#         print(f.readline().strip())
#         print(f.readline().strip())
#         f.write('-----噫嘘唏,蜀道难,难于上青天!------') #想在第二行后插入,结果追加到了末尾
#         print(f.readline().strip())
#         print(f.tell()) #统计打印了多少个字符
#         f.seek(10) #指针回到第十个字符后
#         print(f.tell())
#         print(f.readline().strip()) #从第10个字符后,开始打印

---》》以上方式无法修改

==============只好用以下方式修改================= 

'''
# 修改一个文件
1.像vim一样,先将文件加载到内存里,修改完成后,写回到硬盘
2.打开一个文件A-read,再打开一个文件B-write,将A-read文件的内容逐行写入的B-write,
当遇到A-read中需要修改的内容时,直接将修改的内容写入到B-write,A-read中内容不变,然后
接着将A-read中后续内容,写入到B-write.
'''
with open('song_read','r',encoding='utf-8') as f_read:
    with open('song_write','w',encoding='utf-8') as f_write:
        str='昨日当Alex年少轻狂'
        if f_read.readable():
            for line in f_read:
                if str in line:
                    line=line.replace(str,'昨日当wo年轻狂')
                f_write.write(line)
        else:
            print('song_read is not readable')

---》》with打开两个文件,一个用于读取,一个用于写入;

---》》一行行,边读边写,检索到需要修改的行后(if str in line),修改内容后写入

---》》line.replace()进行修改

==============文件的常用方法================= 

'''
各种方法--->>
# tell方法:read后,返回读取到的字符数
# seek方法:seek(0),返回到最前,光标定位0个字符后
print(f.tell())
print(f.readline().strip())
print(f.readline().strip())
print(f.readline().strip())
#print(f.read(50)) #读取50个字符,无法确定行数
print(f.tell())  #返回读取到的字符数
print(f.seek(0)) #返回第一行,只能返回到第一行,试试seek(10),前10个字符不会打印
print(f.readline()) #打印返回后的行

# encoding,打印文件的编码格式
print(f.encoding)

# 文件编号,操作系统编的。。。
print(f.fileno())

# 是否为终端设备,跟打印机等交互的时用
print(f.isatty())

# 不是所有的文件都可以seek的,像终端文件就无法seek  
print(f.seekable())

# 判断文件是否可读
print(f.readable())

# 判断文件是否可写
print(f.writable())

==============flush方法,写入硬盘================= 

# flush刷新,写入硬盘
>>> f=open('test.txt','w')
>>> f.write('hello1\n')
7
>>> f.flush()
>>> f.write('hello2\n')
7
>>> f.flush()
>>>

 

posted @ 2018-04-09 10:03  尘世①迷途小书童  阅读(297)  评论(0编辑  收藏  举报