第3章 文件操作-函數練習題


'''
1、編碼問題
i請說明python2 與python3中的默認編碼是什么?
答:python2默認編碼是ascii python3默認編碼是:utf-8

ii為什么會出現中文亂碼?你能列舉出現亂碼的情況有哪幾種?
如何進行編碼轉換?
答:編碼不符,程序出錯。
代碼頭代加‘#-*-coding:utf-8-*-’進行聲明轉換

iii#-*-coding:utf-8-*- 的作用是什么?
答:聲明代碼是以utf-8編碼的。

iv解釋py2 bytes vs py3 bytes的區別
答:Python 2 將 strings 處理為原生的 bytes 類型,而不是 unicode,
Python 3 所有的 strings 均是 unicode 類型。

2、文件處理

i r和rb的區別是什么?
'r':默認值,表示從文件讀取數據,rb表示要讀二進制數據

ii解釋一下以下三個參數的分別作用
open(f_name,'r',encoding="utf-8")
答:f_name,表示文件,‘r’表示以只讀模式,encoding ='utf-8',表示解碼為utf-8方式解碼
'''
# names= ['Alex','Black Gril','Peiqi']
#
# def change_name():
# del names[2]
# names[1]= "黑姑娘"
# print(names)
#
# change_name()
# print(names)

#寫函數,計算傳入數字參數的和。(動態傳參)
# x = int(input("輸入要計算的值a:")) #定義動態輸入的x值
# y= int(input("輸入要計算的值b:")) #定義動態輸入的y值
# def calc(x,y):
# res = x + y
# print("結果是:",res)
#
# calc(x,y)
# calc(233,256)

# 2、寫函數,用戶傳入修改的文件名,與要修改的內容,執行函數,完成整個文件的批量修改操作
#文件修改占硬盤
# import os #導入工具箱
# f_name = "兼職白領學生空姐模特護士聯系方式.txt"
# f_new_name = "%s.new"%f_name
#
# old_str = "完成"
# new_str = "美女"
#
# f = open(f_name,'r',encoding='utf-8')
# f_new =open(f_new_name,"w",encoding="utf-8")
#
# for line in f:
# if old_str in line:
# line =line.replace(old_str,new_str)
# f_new.write(line)
# print(line)
#
# f.close()
# f_new.close()
# # os.replace(f_new_name,f_name)
# print("修改完成!")

# 3、寫函數,檢查用戶傳入的對象(字符串、列表、元組)的每個個元素是否含有空內容。
# import os, sys
# res_dir = os.listdir("c:/users")
# for res_list in range(len(res_dir)):
# print( res_list,".",res_dir[res_list])
# dir_num = input("Please Input project number:") #raw_input
# def func(x):
# try:
# x=int(x)
# return isinstance(x,int)
# except ValueError:
# print( "input type is error!!!")
# sys.exit()
# func(dir_num)
# if int(dir_num) >= len(res_dir) or int(dir_num) < 0:
# print("input number is error!!!")
# sys.exit()
# dir_path = "/var/www/html/" + res_dir[int(dir_num)]
# file_name_list = []
# file_path_list = []
# for root, dirs, files in os.walk(dir_path):
# for file_list in files:
# if " " in file_list:
# file_name_list.append(os.path.join(root,file_list))
# for dir_list in dirs:
# if " " in dir_list:
# file_path_list.append(os.path.join(root,dir_list))
# if len(file_name_list) == 0:
# pass
# else:
# print( "Warning: These files has a problem!!!")
# for filelists in file_name_list:
# print( filelists)
# if len(file_path_list) == 0:
# pass
# else:
# print ("\nWarning: These directorys has a problem!!!")
# for dislists in file_path_list:
# print (dislists)

# s = " xyz ".strip() # returns "xyz"
# s1 = " 腳 家 "
# s1 = s1.strip()
# s1=s1.rstrip()
# s1=s1.lstrip()
# print(s1)
# print(s1.strip())
# print(s)
# s2 =" a b c".replace(' ','')#.replace(' ','') 前面帶空格的' '引號被 ‘’不帶空格的引號替換
# print('測試刪中間空格:',s2)

# 4、寫函數,檢查傳入字典的每一個value的度,如果大於2,那么僅保留前兩個長度的內容,並將新內容返回給調用者。
# def a4(v1):
# ret = {}
# for key,value in v1.items():
# if len(value) > 2:
# ret[key] = value[0:2]
# else:
# ret[key] = value
# return ret
# dic = {"k1": "v1v1", "k2": [11, 22, 33, 44],"k3":"12"}
# r = a4(dic)
# print(r)

# 5、解釋閉包的概念
'''關於閉包,即函數定義和函數表達式位於另一個函數體內(嵌套函數)。而且這些函數可以訪問它們所在的外部函數中聲明
的所有局部變量、參數。當其中一個內部函數在包含它們的外部函數之外被調用時,就會形成閉包。也就是說,內部函數會在
外部函數返回后被執行。而當這個內部函數執行時,它仍然必需訪問其外部函數的局部變量、參數以及其它內部函數。這些
局部變量、參數和函數聲明(最初時)的值是外部函數返回時的值,但也會受到內部函數的影響。
閉包的意義:返回的函數對象,不僅僅是一個函數的對象,在該函數外還包裹了一層作用域,這使得,該函數無論在何處
調用,優先使用自己外層包裹的作用域。'''



# 1、寫函數,返回一個撲克牌列表,里面有52項,每一項是一個元組。例如:[(‘紅心’,2), (‘草花’,2), …(‘黑桃,‘A’)]
# def cards():
# num =[]
# for v in range(2,11):
# num.append(v)
# num.extend(['J','Q','K','A'])
# type = ['紅心','草花','方塊','黑桃']
# result = []
# for i in num:
# for j in type:
# result.append((j, i))
# return result
#
# print(cards())


'''# 2、寫函數,傳入n個數,返回字典:{'max':最大值,'min':'最小值'}。例如:min_max(2,5,7,8,4)返回:
{'max':8,'min':2}'''
# def max_min(*args): # *args代表非固定參數。可以有參數,或都沒有參數都可以。 (*args,**kwargs)形參。加多少個參數都可以。
# the_max=args[0]
# the_min=args[0]
# for i in args:
# if i > the_max:
# the_max =i
# if i < the_min:
# the_min=i
# return {'max':the_max,'min':the_min}
# print(max_min(2,4,1,55,-3))


# 3、寫函數,專門計算圓形的面積
'''其中嵌套函數,計算圓的面積,正方形的面積和長方形的面積
調用函數area('圓形',圓半徑)返回圓的面積
調用函數area(正方形,邊長)返回正方形的面積
調用函數area(長方形,長,寬)近回長方形的面積
def area():
def 計算長方形面積():
pass
def 計算正方形面積():
pass
def 計算圓形面積():
pass
'''
#方法一:
# import math
# def area(name,*args):
# def areas_rectangle(x,y):
# return x*y
#
# def area_square(x):
# return x**2
#
# def area_round(r):
# return math.pi*r*r
#
# if name=="圓形":
# return area_round(*args)
# elif name=="正方形":
# return area_square(*args)
# elif name=="長方形":
# return areas_rectangle(*args)
#
# print(area('長方形', 3, 4))
# print(area('圓形', 3))
# print(area('正方形', 3))

# 4、寫函數,傳入一個參數n,返回n的階乘
'''例如:cal(7)
計算7*6*5*4*3*2*1 '''

# def cal(n):
# result=1
# for i in range(n,0,-1):
# result=result*i
# print (i)
# return result
#
# print(cal(8))

'''斐波那契數列:[1,1,2,3,5,8,13,...],每個元素為前兩個元素之和

  (1)當要求長度小於某個值的時候:'''
# l = [1,1] #聲明一個列表,用來存數據
# while len(l)<20: # 當列表長度小於20
# l.append(l[-1]+l[-2]) # l.append(l[-1]+1[-2]) 在最后索引加1代表,表示前兩位遞加,添加值到最后兩位。賦值l列表
# print(l)

'''(2)當要求小於某個數的時候:'''

# l = [1,1]
# while l[-1]<4000000:
# l.append(l[-1]+l[-2])
# del l[-1]
# print(l)

'''
# 正確的整片代碼如下所示:
i = j
j = i+j
# 在這里需要注意,“i, j = i, i+j”這條代碼不能寫成如下所示:
'''

# i, j = 0, 1
# while i < 1000000:
# print(i)
# i, j = j, i+j


'''二、函數裝飾器

  在不修改原函數的內容及調用方式的前提下,對原函數進行功能擴展

1、計算函數執行時間實例'''
# import time
# def timmer(func): #裝飾器
# def innner(*args,**kwargs):
# start=time.time()
# ret=func(*args,**kwargs)
# end=time.time()
# print(start-end)
# return ret
# return innner
#
# @timmer #語法糖,等價name=timmer(name)
# def name(a,b): #被裝飾函數
# print('老板萬歲')
# return a+b
#
# name(4,6)

# 2、打印當前正在調用函數名的實例
# def wrapper(func):
# def inner(*args,**kwargs):
# print('你當前調用的函數是:%s' %func.__name__)
# ret=func(*args,**kwargs)
# return ret
#
# return inner
# @wrapper
# def welcome(name):
# print('welcome,%s' %name)
# welcome('zhangli')
# @wrapper
# def home():
# print('歡迎來到home頁')
# home()

# 5、編寫裝飾器,為多個函數加上認證的功能(用戶的賬號密碼來源於文件),要求登錄成功一次,后續的函數都無需再輸入用戶名
#和密碼
'''
f=open('db.txt','r',encoding='utf-8')
access =f.readlines() #逐行讀取數據
while True: #循環
for line in access:
line=line.split()
for i in range(3):
print(i)
u = input("請輸入用戶名:")
p = input("請輸入密碼:")
if u == line[0] and p == line[1]:
print("登陸成功!")
exit()
else:
print("用戶名或密碼錯誤,請重試!")
if i==2:
exit()
'''
# user_status = False #用戶登錄了 就把這個改成True
# def login(auth_type): #qq
# def outer(func): #henan
# def inner(*args,**kwargs): #3p
# _username = 'alex' #假裝這是DB里存在的用戶信息
# _password = 'abc!23' # 假裝這是DB里存在的用戶信息
# global user_status
#
# if user_status == False:
# username =input("user:")
# password =input("password:")
#
# if username == _username and password ==_password:
# print("welcome login...")
# user_status = True
# else:
# print("wrong username or password!")
# else:
# print("用戶已登錄,驗證通過。。。")
# if user_status:
# func(*args,*kwargs) #3p
# return inner
# return outer
# def home():
# print(" ----首頁----")
# def america():
# print("----歐美專區----")
#
# def japan():
# print("----日韓專區----")
# @login('qq')
# def henan(style):
# print("----河南專區----",style)
#
# henan('3p')

# 生成器和迭代器
#1、生成器和迭代器的區別?
'''對於list、string、tuple、dict等這些容器對象,使用for循環遍歷是很方便的。
在后台for語句對容器對象調用iter()函數。iter()是python內置函數。
iter()函數會返回一個定義了 next()方法的迭代器對象,它在容器中逐個訪問容器內的
元素。next()也是python內置函數。在沒有后續元素時,next()會拋出
一個StopIteration異常,通知for語句循環結束。
迭代器是用來幫助我們記錄每次迭代訪問到的位置,當我們對迭代器使用next()函數的
時候,迭代器會向我們返回它所記錄位置的下一個位置的數據。實際上,在使用next()函數
的時候,調用的就是迭代器對象的_next_方法(Python3中是對象的_next_方法,
Python2中是對象的next()方法)。所以,我們要想構造一個迭代器,
就要實現它的_next_方法。但這還不夠,python要求迭代器本身也是可迭代的,
所以我們還要為迭代器實現_iter_方法,而_iter_方法要返回一個迭代器,
迭代器自身正是一個迭代器,所以迭代器的_iter_方法返回自身self即可。'''

# l=[1,5,6,879,9]
# iterl=iter(l)
# print(iterl.__next__()) #迭代器



# 2、生成器有幾種方式獲取value?
# 兩種方式: for 循環獲取 next 獲取

#3、通過生成器寫一個日志調用方法,支持以下功能
# 根據指令向屏幕輸出日志
#根據指令向文件輸出日志
import logging
class IgnoreBackupLogFilter(logging.Filter):
"""忽略帶db backup 的日志"""
def filter(self, record): #固定寫法
return "db backup" not in record.getMessage()

#console handler
ch = logging.StreamHandler()
ch.setLevel(logging.INFO)
#file handler
fh = logging.FileHandler('mysql.log')
#fh.setLevel(logging.WARNING)


#formatter
'''
# logging.basicConfig(format='%(asctime)s', datefmt='%m/%d/%Y %I:%M:%S %p')
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
#bind formatter to ch
ch.setFormatter(formatter)
fh.setFormatter(formatter)

logger = logging.getLogger("Mysql")
logger.setLevel(logging.DEBUG) #logger 優先級高於其它輸出途徑的

#add handler to logger instance
logger.addHandler(ch)
logger.addHandler(fh)
#add filter
logger.addFilter(IgnoreBackupLogFilter())

logger.debug("test ....")
logger.info("test info ....")
logger.warning("start to run db backup job ....")
logger.error("test error ....")
'''
# 內置函數
# 1、用map 來處理字符串列表,把列表中所有人都變成sb,比方alex_sb
# name = ['alex','wupeiqi','yuanhao','zezha']
'''map()函數
map()是 Python 內置的高階函數,它接收一個函數 f 和一個 list,並通過把
函數 f 依次作用在 list 的每個元素上,得到一個新的 list 並返回。

例如,對於list [1, 2, 3, 4, 5, 6, 7, 8, 9]

如果希望把list的每個元素都作平方,就可以用map()函數:
因此,我們只需要傳入函數f(x)=x*x,就可以利用map()函數完成這個計算:

def f(x):
return x*x
print map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])
輸出結果:

[1, 4, 9, 10, 25, 36, 49, 64, 81]
注意:map()函數不改變原有的 list,而是返回一個新的 list。'''

# name = ['alex', 'wupeiqi', 'yuanhao', 'zezha']
# def s1(x):
# return x+'_sb'
# a = map(s1,['alex', 'wupeiqi', 'yuanhao', 'zezha'])
#
# print("函數:",list(a))

# def s1(x):
# return x+'_sb'
# a= map(s1,['alex', 'wupeiqi', 'yuanhao', 'zezha'])
# print('name=',list(a))
# 用filter函數處理數字列表,將列表中所有的偶數篩選出來
##num = [1,3,5,6,7,80.]

# num = [1,3,5,6,7,8]
# def func(x):
# if x%2 == 0:
# return True
# ret = filter(func,num) #ret是迭代器
# print(list(ret))
#
# ret = filter(lambda x:x%2 == 0,num)
# ret = filter(lambda x:True if x%2 == 0 else False,num)
# print(list(ret))

'''自己寫的例子'''
# num = [1,3,5,6,7,8]
# def func(x):
# if x%2 ==0:
# return True
# ret =filter(func,num) #ret是迭代器
# print(list(ret))
# ret1 = filter(lambda x:x%2==0,num)
# print("lambda",list(ret1))
# ret2 = filter(lambda x:True if x%2==0 else False,num)
# print("ret2",list(ret2))
'''
3.用map來處理字符串列表,把列表中所有人都變成sb,比方alex_sb
name = [‘alex‘,‘wupeiqi‘,‘yuanhao‘,‘nezha‘]
def ad(l):
return l[:len(l)]+‘_sb‘
print(list(map(ad, name)))
'''
# 3、 如下,每個小字典對應股票名字,shares對應多少股,price對應股票的價格
'''portlio= [
{'name':'IBM','shares':100,'price':91.1},
{'name':'AAPL','shares':50,'price':543.22},
{'name':'FB','shares':200,'price':21.09},
{'name':'HPQ','shares':35,'price':31.75},
{'name':'YHOO','shares':45,'price':16.35},
{'name':'ACME','shares':75,'price':115.65}
]
計算購買每支股票的總價
用filter過濾出,單價大於100的股票有些'''

'''
2'用filter函數處理數字列表,將列表中所有的偶數篩選出來
num = [1,2,3,4,5,6,7,8]
def ou(num1):
return num1 % 2 == 0
print(list(filter(ou,num)))
'''

'''
3.如下,每個小字典的name對應股票名字,shares對應多少股,price對應股票的價格

portfolio = [
{'name': 'IBM', 'shares': 100, 'price': 91.1},
{'name': 'AAPL', 'shares': 50, 'price': 543.22},
{'name': 'FB', 'shares': 200, 'price': 21.09},
{'name': 'HPQ', 'shares': 35, 'price': 31.75},
{'name': 'YHOO', 'shares': 45, 'price': 16.35},
{'name': 'ACME', 'shares': 75, 'price': 115.65}
]
計算購買每支股票的總價

用filter過濾出,單價大於100的股票有哪些


'''
# 1、map來得出一個包含數字的迭代器,數字指的是:購買每支股票的總價格

portfolio = [
{'name': 'IBM', 'shares': 100, 'price': 91.1},
{'name': 'AAPL', 'shares': 50, 'price': 543.22},
{'name': 'FB', 'shares': 200, 'price': 21.09},
{'name': 'HPQ', 'shares': 35, 'price': 31.75},
{'name': 'YHOO', 'shares': 45, 'price': 16.35},
{'name': 'ACME', 'shares': 75, 'price': 115.65}
]
# m = map(lambda y:y["shares"]*y["price"],portfolio)
# print(list(m))
# --------------輸出結果---------------
# [9110.0, 27161.0, 4218.0, 1111.25, 735.7500000000001, 8673.75]

#  3、用filter過濾出,單價大於100的股票有哪些

# f =filter(lambda d:d['price']>=100,portfolio)
# print(list(f))
# -----------------------輸出結果-----------------------------
# [{‘name‘: ‘AAPL‘, ‘shares‘: 50, ‘price‘: 543.22}, {‘name‘: ‘ACME‘, ‘shares‘: 75, ‘price‘: 115.65}]
'''
1、請分別介紹文件操作中不同的打開方式之間的區別:

模式 含義
r 文本只讀模式
rb 二進制模式  #這種方法,是用來傳輸或存儲,不給人看的。
r+ r+ 是讀寫模式,只要沾上r,文件必須存在
rb+ 二進制讀寫模式
w w 寫模式,它是不能讀的,如果用w模式打開一個已經存在的文件,會清空以前的文件內容,重新寫
wb 和wb 兩種模式
w+ w+ 是讀寫內容,只要沾上w,肯定會清空原來的文件
wb+ 二進制寫讀模式
a a 追加模式,也能寫,在文件的末尾添加內容
ab 二進制追 加模式
a+
ab+
'''
# 2、有列表 li = ['alex', 'egon', 'smith', 'pizza', 'alen'], 請將以字母“a”開頭的元素的首字母改為大寫字母

# li = ['alex', 'egon', 'smith', 'pizza', 'alen']
# for i in range(5):
# if "a" == li[i][0]:
# li[i] =li[i].capitalize()
# print("大寫后",li[i][0])
# else:
# continue
#
# print(li)
'''
5、有名為poetry.txt的文件,其內容如下,請刪除第三行;

昔人已乘黃鶴去,此地空余黃鶴樓。

黃鶴一去不復返,白雲千載空悠悠。

晴川歷歷漢陽樹,芳草萋萋鸚鵡洲。

日暮鄉關何處是?煙波江上使人愁。
'''
# import os
# p='poetry.txt'
# poetry =open(p,'r',encoding='utf-8')
# poetry_new= '%s.new'%p
# p_new=open(poetry_new,'w',encoding='utf-8')
# str1='晴川歷歷漢陽樹,芳草萋萋鸚鵡洲。'
# for line in poetry:
# if str1 in line:
# line= ''
# p_new.write(line)
# print(str1)
# else:
# p_new.write(line)
# poetry.close()
# p_new.close()
# os.replace(poetry_new,p)

#方法二 逐行讀取文件,
# import os
# f1=open('poetry.txt', 'r',encoding='utf-8')
#
# str='晴川歷歷漢陽樹,芳草萋萋鸚鵡洲。'
# with open('poetry1.txt', 'w', encoding='utf-8') as f2:
# ff1='poetry.txt'
# ff2='poetry1.txt'
# for line in f1:
# if str in line:
# line=''
# f2.write(line)
#
# else:
# f2.write(line)
# f1.close()
# f2.close()
# os.replace(ff2,ff1)
'''
6、有名為username.txt的文件,其內容格式如下,寫一個程序,判斷該文件中是否存在"alex", 如果沒有,則將字符串"alex"添加到該文件末尾,否則提示用戶該用戶已存在;

pizza
alex
egon '''
# usr=open('username.txt','r+',encoding='utf-8')
# str="alex"
# for line in usr:
# if str in line:
# print('該用戶已存在,程序退出!')
# exit()
# usr.close()
# usr=open('username.txt','a',encoding='utf-8')
# usr.write('\nalex')
# usr.close()
# print("用戶添加成功!")
'''
7、有名為user_info.txt的文件,其內容格式如下,寫一個程序,刪除id為100003的行;

pizza,100001
alex, 100002
egon, 100003 '''

# import os
# u1='user_info.txt'
# u2='%s.new'%u1
# with open('user_info.txt','r+',encoding='utf-8') as f1:
# with open("%s.new"%u1,'w',encoding='utf-8')as f2:
# for line in f1:
# if "100003" in line:
# line =""
# f2.write(line)
# else:
# f2.write(line)
# os.replace(u2,u1)

'''
8、有名為user_info.txt的文件,其內容格式如下,寫一個程序,將id為100002的用戶名修改為alex li;

pizza,100001
alex, 100002
egon, 100003 '''

# file='user_info.txt'
# oldstr='100002'
# newstr='alex, 100002'
# file_data=''
# with open(file,'r',encoding='utf-8') as f1:
#
# for line in f1:
# if oldstr in line:
# line =newstr
# file_data +=line
#
# with open(file,'w',encoding='utf-8') as f1:
# f1.write(file_data)


# 9、寫一個計算每個程序執行時間的裝飾器;
#-*-coding:utf-8 -*-
#-*- coding: utf-8 -*-


import time

"""
定義簡單的裝飾器,用來輸出程序運行的所用時間
"""
'''
def timer(func):
def decor(*args):

start_time = time.time();
func(*args);
end_time = time.time();
d_time = end_time - start_time
print("run the func use : ", d_time)


return decor;

@timer #printSth = timer(printSth) -> printSth = decor
def printSth(str, count):
for i in range(count):
print("%d hello,%s!"%(i,str))
printSth("world", 100)
'''


# 10、lambda是什么?請說說你曾在什么場景下使用lambda?
'''
lambda函數就是可以接受任意多個參數(包括可選參數)並且返回單個表達式值得函數
好處:
1.lambda函數比較輕便,即用即扔,適合完成只在一處使用的簡單功能
2.匿名函數,一般用來給filter,map這樣的函數式編程服務
3.作為回調函數,傳遞給某些應用,比如消息處理'''
'''
什么是裝飾器?寫一個裝飾器,可以打印輸出方法執行時長的信息。
裝飾器模式(Decorator Pattern)允許向一個現有的對象添加新的功能,同時又不改變其結構。這種類型的設計模式屬於結構型模式,它是作為現有的類的一個包裝。
這種模式創建了一個裝飾類,用來包裝原有的類,並在保持類方法簽名完整性的前提下,提供了額外的功能。
我們通過下面的實例來演示裝飾器模式的用法。其中,我們將把一個形狀裝飾上不同的顏色,同時又不改變形狀類。
import time

def timer(func):
def decor(*args):

start_time = time.time()
func(*args)
end_time = time.time()
d_time = end_time - start_time
print("run the func use : ", d_time)
return decor

@timer #printSth = timer(printSth) -> printSth = decor
def printSth(str, count):
for i in range(count):
print("%d hello,%s!"%(i,str))

printSth("world", 1000000)#run the func use : 4.414000034332275

'''
''''''


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM