【Python之路Day3】基礎篇

今日目錄:html

1. setpython

2. 函數git

3. 內置函數github

4. 文件操做面試

5. 三元運算數據庫

6. lambda表達式 編程

7. 全局變量數組

一. set緩存

set是Python基本數據類型中的一種,主要特性是: 無序、不重複的序列,基本功能包括關係測試(如父集子集等)、消除重複的元素等。set集合還支持difference(差集)、intersection(交集)、union(聯合)、sysmmetric difference(對稱差集)等數學運算。學習set仍是按照兩步驟來:1.建立 2.功能app

1. 建立set集合

 

>>> s = set('daniel')
>>> s
{'d', 'n', 'e', 'l', 'i', 'a'}
>>> type(s)
<class 'set'>

 

或者:

>>> s1 = {'a','b','c',}
>>> s1
{'a', 'c', 'b'}
>>> type(s1)
<class 'set'>

注意若是要建立一個空集合,必須使用set()了,s={} 默認的是字典類型,須要使用s=set()才行

>>> s1 = {}
>>> type(s1)
<class 'dict'>
>>> s1 = set()
>>> type(s1)
<class 'set'>
>>> 

能夠試着嘗試下傳入一個列表進去:

>>> l1 = [1,2,3,4,5,5,4,3,2,1,1,2,3,4,5]
>>> s4 = set(l1)
>>> s4
{1, 2, 3, 4, 5}   #能夠看到set的不重複特性
 

2. 操做方法

add 往set裏添加元素

>>> s1
{1, 2, 3, 4, 5}
>>> s1.add(6)
>>> s1
{1, 2, 3, 4, 5, 6}
#add()方法一次只能接受一個參數,也就是隻能添加一個元素到set裏
>>> s1.add(7,8,9)  #一次加3個會報錯
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: add() takes exactly one argument (3 given)
#經過字符串形式添加,看可否一次添加多個
>>> l3='789abc'
>>> s1.add(l3)
>>> s1
{1, 2, 3, 4, 5, 6, '789abc'}   #也是把一個字符串當成一個參數來添加

clear  清空set

>>> s1
{1, 2, 3, 4, 5, 6, '789abc'}
>>> s1.clear()
>>> s1
set()

copy  複製

>>> s1
{1, 2, 3, 4, 5, 6, '789abc'}
>>> s2 = s1.copy()
>>> id(s1)
139851744274920
>>> id(s2)
139851744275368

difference 取差集

>>> s1 = {1,3,4,5,}
>>> s2 = {3,1,7,9}
>>> s1.difference(s2)  #A裏有的元素,B裏沒有的元素
{4, 5}

intersection 取交集

>>> s1 = {1,3,4,5,}
>>> s2 = {3,1,7,9}
>>> s1.intersection(s2)  #A和B都有的元素
{1, 3}

symmetric_difference  對稱差集

>>> s1 = {1,3,4,5,}
>>> s3 = {11,22,3,4}
>>> s1.symmetric_difference(s3) #A中有,B沒有,B有,A沒有的元素
{1, 5, 11, 22}

difference_update  intersection_update symmetric_difference_update 這三個放在一塊兒說,主要是帶update會更新原始數據:

>> s1
{1, 3, 4, 5}
>>> s2
{9, 1, 3, 7}
>>> s1.difference_update(s2)
>>> s1  #s1的值已經變成了s1和s2的交集的結果
{4, 5}
>>> s2  #s2的值沒變
{9, 1, 3, 7}

#intersection_update
>>> s2
{9, 1, 3, 7}
>>> s3
{3, 4, 11, 22}
>>> s2.intersection_update(s3)
>>> s2   #s2的值變成兩個交集的結果
{3}
>>> s3  #s3不變
{3, 4, 11, 22}


#symmetric_difference_update
>>> s3
{3, 4, 11, 22}
>>> s4
{3, 44, 11, 22, 55}
>>> s3.symmetric_difference_update(s4)
>>> s3  #取兩個集合的對稱差集寫入到s3中了
{4, 55, 44}
>>> s4  #s4不變
{3, 44, 11, 22, 55}
View Code

discard 若是set中存在某元素,就刪除

>>> s1
{4, 5}
>>> s1.discard(60)  #set中沒有60元素,因此沒返回任何消息
>>> s1
{4, 5}
>>> s1.discard(5)   #set中有元素5,因此,元素被刪除
>>> s1
{4}

pop 刪除元素,set是無序的,所以也是隨機刪除元素,可是會返回刪除的這個元素值,pop的特性,在Python的數據類型中都是這種,刪除後會返回這個刪除元素;

>>> s4
{3, 44, 11, 22, 55}
>>> s4.pop()
3
>>> s4.pop(55)
>>> s4.pop()
44
View Code

remove 刪除指定的元素,必需要返回一個值

>>> s4
{11, 22, 55}
>>> s4.remove(44)   #因爲set中沒有44元素,因此報錯
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 44
>>> s4.remove(55)  #刪除55元素
>>> s4
{11, 22}

issubset  是不是子集,是爲True,否爲False

>>> s3
{4, 55, 44}
>>> s4
{33, 11, 44, 22, 55}
>>> s3.issubset(s4)  #s3不是s4的子集,返回爲False
False
>>> s4.issubset(s3)
False
>>> s5 = {11,22,33}
>>> s5.issubset(s4)  #s5是s4的子集,返回True
True
View Code

issuperset 是不是父集,是爲True,否爲False

>>> s4
{33, 11, 44, 22, 55}
>>> s5
{33, 11, 22}
>>> s4.issuperset(s5)  #s4是s5的父集合,返回True
True
View Code

union 聯合,數據能夠是字符串、list、dict、int任意類型,而且會把元素拆開,去重以後添加到set中,可是,若是須要保存的話,應該賦值給一個變量

>>> l1 = [1,2,3,4,5,]  #建立一個列表

>>> s3 #查看s3之前元素
{4, 55, 44}
>>> s3.union(l1)  #將l1中的每個元素遍歷,並加入到sets中打印出來
{1, 2, 3, 4, 5, 44, 55}
>>> s3  #s3中的元素仍是沒有變,因此如需保存,應該賦值給變量
{4, 55, 44}
>>> str1='daniel'  #建立一個字符串 
>>> s3.union(str1) #union會將字符串拆分,去重後加入set打印
{4, 'l', 44, 'i', 55, 'a', 'n', 'e', 'd'}
>>> t1 = (3,4,5,6,) #tuple同樣
>>> s3.union(t1)
{3, 4, 5, 6, 44, 55}
>>> t1 = (3,4,5,6,99,0,234,441,34,)
>>> s3.union(t1)
{0, 34, 3, 4, 5, 6, 99, 234, 44, 55, 441}
>>> d1 = {'k1':'v1','k2':'v2','k3':[1,3,3,4,55,]}  #字典默認會遍歷全部key而後加入到set打印
>>> s3.union(d1)
{'k3', 'k2', 4, 55, 44, 'k1'}

update,和union同樣,都是擴充/添加元素到set,惟一不一樣的是update會寫入原有集合中,而union不會

>>> s1='daniel'   #先建立一個字符串
>>> s2 = {'a','b','c'} #含有abc元素的set
>>> s2
{'a', 'c', 'b'}
>>> s2.update(s1)  #加入元素s1
>>> s2
{'l', 'c', 'b', 'i', 'a', 'n', 'e', 'd'}  #結果是直接寫入到s2的set中
>>> l1 = [1,2,23,4,5,6,]
>>> s2
{'l', 'c', 'b', 'i', 'a', 'n', 'e', 'd'}
>>> s2.update(l1)
>>> s2
{1, 2, 4, 'l', 'c', 5, 6, 'b', 'i', 23, 'a', 'n', 'e', 'd'}

isdisjoin 判斷兩個set中是否有交集,有返回True,不然返回False

>>> s2
{1, 2, 4, 'l', 'c', 5, 6, 'b', 'i', 23, 'a', 'n', 'e', 'd'}
>>> s3
{4, 55, 44}
>>> s2.isdisjoint(s3)
False

3. 練習題

尋找差別

 

#需求: 
#以下數據,假設是一個CMDB,老的數據庫中的數據(內存槽位):
old_dic = {
    '#1': 8,
    '#2': 4,
    '#4': 2,
}
#新採集的數據,
new_dic = {
    '#1': 4,
    '#2': 4,
    '#3': 2,
}
# 槽位1,槽位2值發生變化須要更新數據到老的數值
# 槽位4發生變化,已經移除,須要刪除數據
# 槽位3發生變化,新增槽位,須要插入記錄

 

old_dic = {
    '#1': 8,
    '#2': 4,
    '#4': 2,
}

new_dic = {
    '#1': 4,
    '#2': 4,
    '#3': 2,
}
#將新老數值的key值取出,並轉換成set類型
old_dic1 = set(old_dic.keys())
new_dic1 = set(new_dic.keys())

#A和B取差集,找到要刪除的槽位
print('要刪除的槽位是: %s' %old_dic1.difference(new_dic1))
#A和B取交集,找到須要更新的槽位
print('要更新的槽位是: %s' %old_dic1.intersection(new_dic1))
#B和A取差集,找到要插入的槽位
print('要增長的槽位爲: %s' %new_dic1.difference(old_dic1))

 

 

二. 函數

函數說白了就是一組代碼集合,用於在程序中反覆調用,解決代碼重複編寫的問題。兩天的做業中,基本上都是堆積代碼實現的,次日的購物車程序更是碼了近400行,根據做業需求邏輯從上到下一步一步碼代碼,一個打印功能就寫了四處代碼,並且一旦修改重複功能的話,全部的地方都要修改。這個是面向過程的編程方式。若是用到函數的話,代碼首先變的很簡潔,另外,review代碼的人也比較容易看懂代碼,畢竟程序不是一我的來編寫的,即使是一我的編寫的,過幾天做者都有可能忘記本身寫的代碼段的功能了,因此函數式編程+良好的註釋是一個很好的習慣和修養。

以下一個實例,驗證用戶登陸身份,1:登陸程序  2: 註冊用戶,若是用到面向過程編程的話,代碼看起來是介樣子的:

user_input_num = input('1. 登陸程序  2.註冊用戶').strip()
if user_input_num == '1':
    user_input_name = input('請輸入用戶名:').strip()
    user_input_pass = input('請輸入密碼:').strip()
    with open('user.db','r') as f:
        for line in f:
            if user_input_name == line.strip().split()[0] and user_input_pass == line.strip().split()[1]:
                print('登陸成功')
                break
        else:
            print('登陸失敗,用戶名或者密碼錯誤')
if user_input_num == '2':
    user_input_name = input('請輸入用戶名:').strip()
    user_input_pass = input('請輸入密碼:').strip()
    with open('user.db','r+') as f:
        for line in f:
            if user_input_name == line.strip().split()[0]:
                print('用戶名太搶手,已經被註冊啦')
        else:
            user_info = '\n' + user_input_name + ' ' + user_input_pass
            f.write(user_info)
            print('%s,恭喜你,註冊成功' %user_input_name)

而使用函數式編程是這樣的:

def login(username,password):
    '''
    用戶登陸程序
    :param username:接受用戶輸入的用戶名
    :param password: 接受用戶輸入的密碼
    :return: True:表示認證成功,False:表示認證失敗
    '''
    #with open('user.db','r') as f:
    f = open('user.db','r')
    for line in f.readlines():
        if line.strip().split()[0] == username and line.strip().split()[1] == password:
            return True
    else:
        return False


def registry(user,passwd):
    '''
    用戶註冊函數
    :param user: 接受用戶傳入註冊用的用戶名
    :param passwd: 接受用戶傳入的註冊密碼
    :return: 若是用戶不存在,而且寫入用戶名到文件成功後返回True,不然返回False
    '''
    with open('user.db','r+') as f:
        for line in f:
            if user == line.strip().split()[0]:
                return True
        else:
            info = '\n' + user + ' ' + passwd
            f.write(info)
            return False


def main():
    user_select = input('1:登陸程序, 2:註冊用戶').strip()
    if user_select == '1':
        username = input('請輸入用戶名:').strip()
        password = input('請輸入密碼:').strip()
        r = login(username,password)
        if r:
            print('登陸成功')
        else:
            print('登陸失敗,用戶名或密碼錯誤')

    if user_select == '2':
        user_input_name = input('請輸入用戶名:').strip()
        passwd_input = input('請輸入密碼:').strip()
        R = registry(user_input_name,passwd_input)
        if R:
            print('用戶名太搶手,已經被註冊了!')
        else:
            print('註冊成功!')

if __name__ == '__main__':
    main()

好吧,這個例子不太明顯,由於代碼量少,看看我寫的次日的做業購物車程序例子吧:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Author: DBQ(Du Baoqiang)

'''
Author: DBQ
Blog: http://www.cnblogs.com/dubq/articles/5497639.html
Github: https://github.com/daniel-vv/ops
'''

import time
import sys
import os
import pickle
import getpass


def User_Input_salary():
    '''
    定義一個函數,用於接收用戶輸入工資金額
    '''
    Flag = False
    while not Flag:
        User_salary = input('請輸入您預消費的金額(元):').strip()
        if User_salary.isdigit():
            User_salary=int(User_salary)
            Flag = True
            if User_salary >= 200000:
                print('-'*50)
                print('\033[34;1m臥槽,碉堡了,土豪,咱們朋友吧~\033[0m')
                print('-'*50)
        else:
            print('抱歉,您輸入的 \033[31;1m%s \033[0m不是一個合法的工資/金額'%User_salary)

    return User_salary

def Deny_user(username):
    '''定義一個寫入用戶信息到黑名單的函數,在後面的時候調用直接將鎖定用戶信息寫入到鎖文件中去'''
    with open('db/locked.db','a+') as f:
        print('\033[1;31m抱歉,用戶 %s 輸入次數太多, 已被鎖定,請聯繫管理員解鎖!' %username)
        f.write('%s\n' %username)

#定義一個字典,用於下面驗證用戶身份,帳戶名密碼經過key:value的形式存儲在字典中
user_list = {
    'tom':'123',
    'jerry':'123',
    'jack':'123',
}

def username():
    '''
    定義一個函數,用於接收用戶輸入用戶名密碼的驗證
    若是用戶名在鎖定文件locked.db中,直接返回給用戶已被鎖定,退出程序
    判斷用戶輸入是不是同一用戶輸入三次錯誤嘗試,若是是,則鎖定用戶,不然三次以後退出程序;
    '''
    Flag = False
    Count = 0
    Lock_count = 1
    user_name = ''
    while Count < 3:
        User_input_name = input('請輸入您的用戶名: ').strip()
        if User_input_name:
            User_input_name = str(User_input_name)
            User_input_pass = getpass.getpass('請輸入您的密碼: ').strip()
            with open('db/locked.db','r') as f:
                for i in f:
                    if User_input_name == i.strip():
                        print('\033[31;1m您的用戶已經被鎖定,請聯繫管理員解鎖!\033[0m')
                        exit(0)
            if User_input_name == user_name:
                Lock_count += 1
            else:
                user_name = User_input_name
                Lock_count -= 1
            for user,passwd in user_list.items():
                if User_input_name == user and User_input_pass == passwd: #判斷用戶名和密碼認證是否成功
                    print('\033[32;1m歡迎登錄 %s\033[0m'.center(50,'#') %User_input_name)
                    Flag = True
                    break
                if Flag:
                    break
            else:
                print('用戶名或密碼不正確,請從新輸入')
                #print(User_input_name)
                #print(User_input_pass)

                Count += 1
                ##if User_input_name
        if Flag:
            break
    else:
        if Lock_count == 2:
            Deny_user(User_input_name)
        exit(0)
    #user_info.remove(User_input_name)
    #if len(data) != 0:
        #del user_info[User_input_name]
        #return User_input_name,user_info,User_salary
    #else:
        #return User_input_name
    return User_input_name




##定義商品列表
commodity_list = {
    '家電類':{
        '西門子冰箱':4998,
        '美的空調':3912,
        '微波爐':1248,
        '飲水機':328,
        '樂視 Max70':9979,
        '小米電視 ':4199,
        '洗衣機':3328,
        '格力空調':2889,
        'MacBook Pro':10899,
        '高壓力鍋':399,
        '電磁爐':198,
        '淨水器':1999,
        '濾水壺':599,
    },
    '圖書類':{
        '小姨多鶴':37.9,
        '向着光明那方':29.9,
        '百年孤獨':39.9,
        '了不得的蓋茨比':21.8,
        '扶桑(嚴歌苓)':32.8,
        '陸犯焉識':39.8,
        '孩子你慢慢來':25.8,
        '魚羊野史套裝':146.8,
        '明朝那些事兒':166.7,
        '活着(餘華做品)':15.6,
        '皮囊(蔡崇達)':21.8,
        '目送(龍應臺)':23.8,
        '三體(國內最牛x科幻)':188,
        '失樂園':33.0,
    },
    '衣服類':{
        '棒球帽':99,
        'T恤':199,
        '皮帶':299,
        'Adidas鞋':899,
        'Nike鞋':899,
        'Puma鞋':768,
        '皮鞋':699,
        'Lee牛仔褲':409,
        '內褲':49,
        '運動襪':29,
        '休閒西服上':499,
        '七分褲':249,
        '休閒家居服':199,
        '匡威雙肩包':269,
        '仿古蛤蟆鏡':298,
        '鞋墊':38,
    },
    '手機類':{
        'iPhone 6s 16G':4987,
        'iPhone 6s 64G':5688,
        'iPhone 6sP 16G':6088,
        'iPhone 6sP 64G':6888,
        '錘子堅果':899,
        '小米Max':1999,
        'Samsung S7':5688,
        '華爲P9':3688,
        '魅族MX5':1999,
        'Nexus6':3300,
    },
    '汽車類':{
        '寶馬 7':1200000,
        '寶馬 5':660000,
        '寶馬 3':380000,
        'Tesla ModelS':790000,
        '速騰':160000,
        '邁騰':210000,
        '甲殼蟲':250000,
        '高爾夫':180000,
        '卡羅拉':130000,
        '邁銳寶':150000,
        '凱美瑞':210000,
    },
    '菸酒類':{
        '玉溪':22,
        '中華':45,
        '利羣':14,
        '南京':13,
        '芙蓉王':19,
        '白沙':10,
        '蓯蓉':13,
        '雲煙':11,
        '長白山':11,
        '老白汾':398,
        '白玉汾酒':198,
        '玫瑰汾酒':298,
        '五糧液':499,
        '衡水老白乾':198,
        '茅臺':399,
        '夢之藍':398,
        '郎酒':398,
        '天之藍':298,
    },
}

user_shopping_db = 'db/user_shopping.db'
shopp_car = '{0}    {1}         {2}     {3}     {4}'
#user_file = open(user_shopping_db,'rb')
data = open(user_shopping_db,'rb').read()
if len(data) != 0:
    user_data = len(pickle.load(open(user_shopping_db,'rb')))
    user_info = pickle.load(open(user_shopping_db,'rb'))
else:
    user_data = 0

user_shopping = {}  #定義一個空字典,用於存儲用戶的購物車信息
Flag = False        #定義標誌位,用於進入循環
User_flag = False   #定義一個用戶標誌位,用於判斷用戶是否有認證,防止後面循環會要求用戶反覆認證


while not Flag:     #進入循環主題
    if not User_flag:   #根據定義用戶標誌位來判斷
        user = username()   #將上面定義函數實例化,並賦值給user變量
        if user_data != 0:  #判斷變量非空進入下面驗證,取出用戶上一次登陸程序
            for i in user_info.keys():
                if user == i:
                    id = 1
                    for k,v in user_info.items():
                        if user == k:
                            #shopp_car = '{0}    {1}         {2}     {3}     {4}'
                            print('\033[32;1m歡迎您, %s, 您上一次的餘額爲 %s\033[0m'%(k,user_info[user]['salary']))
                            print('購物車的內容以下'.center(70,'-'))
                            print('\033[34;1m序列       寶貝名            數量      小計      購買時間\033[0m') #先打印title
                            User_salary = user_info[user]['salary']
                            del user_info[user]['salary']

                        for k1,v1 in user_info[user].items():
                            if user != k1:
                                print(shopp_car.format(id,k1,v1[0],v1[1],v1[2],))
                                id +=1
                                #continue
                        else:
                            print('-'*70)
                    #if input('按下任意鍵繼續...'):pass
                    #del user_info[user]
                    user_shopping = user_info
                else:
                    User_salary = User_Input_salary()
                    pass
        else:
            User_salary = User_Input_salary()   #實例化用戶輸入消費金額函數並複製給變量

        print('~Bingo, 歡迎 [ %s ] 來到 DBQ 的百貨店,請選擇您須要的寶貝以及數量,祝您購物愉快~'.center(70,'#')%user)

    for id,keys in enumerate(commodity_list.keys()):  #進入三級菜單
        print(id,keys)
    User_id = input('\033[33;1m請選擇您感興趣的分類  Q/q(退出程序) C/c(檢查購物車)\033[0m').strip()
    if User_id == 'q' or User_id == 'Q':  #判斷是Q/q,退出程序
        print('歡迎下次再來 [ %s ], bye!'%user)
        Flag = True
        break
    if User_id == 'c' or User_id == 'C':  #若是是c/C,檢查用戶購物車,若是購物車爲空,提示用戶爲空
        if len(user_shopping) != 0:  #判斷若是用戶購物車不爲空是顯示購物車信息
            print('購物車'.center(70))
            print('-'*70)
            print('\033[34;1m序列       寶貝名            數量      小計      購買時間\033[0m') #先打印title
            product_index = 1 #定義一個序列ID
            user_consume = 0 #定義一個值爲0的用戶消費金額初始值,用於下面累加用戶這次消費總金額
            #print(user_shopping)
            for value in user_shopping[user].keys():
                #print(value)
                #print(shopp_car.format(product_index,index,value[1][0],value[0][1],value[0][2],))
                print(shopp_car.format(product_index,value,user_shopping[user][value][0],user_shopping[user][value][1],user_shopping[user][value][2],))
                user_consume += user_shopping[user][value][1] #自增用戶消費金額
                product_index += 1 #序列ID自增
            print('-'*70)
            print('\033[34;1m親愛的用戶[ %s ], 共消費 [ %s ]元, 您的餘額 [ %s ]元\033[0m'%(user,user_consume,User_salary))

            if input('\033[31;1m 按下任意鍵繼續...\033[0m'):pass
        else: #若是購物車爲空,提示用戶購物車爲空,並返回商品列表
            print('-'*50)
            print('抱歉,你還未購買任何寶貝,購物車裏空到不行不行的~')
            print('-'*50)
    if User_id.isdigit() and int(User_id) < len(commodity_list.keys()):
        product = list(commodity_list.keys())[int(User_id)]  #將字典轉換爲有序列表
        while not Flag:
            for id2,key2 in enumerate(commodity_list[product].items()):  #進入商品明細,供用戶選擇序號購買
                print(id2,key2)
            print('#'*70)
            User_id2 = input('\033[33;1m請選擇您須要的寶貝序列添加到購物車:  Q/q(退出程序) B/b(返回) C/c(檢查購物車)\033[0m'.center(30,'#')).strip()
            if User_id2.isdigit() and int(User_id2) < len(commodity_list[product]):
                #print(commodity_list[product][int(User_id2)])
                product1 = list(commodity_list[product].keys())[int(User_id2)]
                price = int(commodity_list[product][product1])
                print('您已經選擇了寶貝\033[32;1m %s \033[0m, 寶貝價格(元):\033[32;1m %s \033[0m'%(product1,price))
                product_num = input('請輸入你欲購買的寶貝\033[32;1m %s \033[0m數量:'%product1).strip()
                if product_num.isdigit() and product_num and int(product_num) != 0:
                    product_num = int(product_num)
                    price *= product_num
                    if price <= User_salary:
                        User_salary -= price
                        product_time = time.strftime('%Y-%m-%d %H:%M:%S',time.localtime())  #返回當前購買時間給一個變量
                        #if product1 not in user_shopping.get(user): #判斷若是用戶購買的商品不在購物車中直接setdefault值爲新商品信息
                        if not user_shopping.get(user):
                            #user_shopping[user]=
                            #user_shopping[user] = [{product1,[product_num,price,product_time,]}]
                            user_shopping[user] = {product1:[product_num,price,product_time,]}

                        else:  #若是存在購物車中,更新現有信息
                            #print(user_shopping[user][product1][0][0])
                            user_shopping[user].setdefault(product1,[product_num,price,product_time,])
                            print(user_shopping)
                            product_num += user_shopping[user][product1][0] #累加商品數量
                            print(user_shopping[user][product1][0])
                            price += user_shopping[user][product1][1]  #累加商品金額
                            user_shopping[user][product1][0] = product_num  #從新修改購物車中的值
                            user_shopping[user][product1][1] = price
                            user_shopping[user][product1][2] = product_time
                        #user_shopping[product_id] = [product1,product_num,price,product_time]
                        #打印購買成功信息,包括用戶購買商品\金額以及餘額
                        print('恭喜你,成功購買寶貝\033[32;1m %s \033[0m數量\033[32;1m %s \033[0m,' \
                              '這次消費\033[32;1m %s (元) \033[0m, 餘額:\033[32;1m %s \033[0m' \
                              %(product1,product_num,price,User_salary))
                        print('#'*70)
                        continue
                    else: #輸入用戶餘額不足,提示用戶充值
                        pay = input('\033[31;1m抱歉,您的餘額[ %s ],寶貝價格[ %s ],餘額不足,不能購買此寶貝,是否充值? (y/Y)\033[0m'%(User_salary,price)).strip()
                        if pay and pay == 'y' or pay == 'Y':  #輸入y/Y爲確認充值
                            pay_money = input('請輸入要充值的金額:').strip()  #充值金額
                            if pay_money.isdigit() and int(pay_money) != 0: #若是是數字並且充值金額不能爲0
                                User_salary += int(pay_money)  #用戶餘額+=新充值金額,並賦值給餘額變量
                                time.sleep(1)
                                print('-'*50)
                                print('充值成功,帳戶最新餘額:\033[31;1m [ %s ] 元\033[0m'%User_salary) #打印充值成功
                                if User_salary >= 200000:  #若是用戶充值金額大於等於20W,絕對是土豪身份
                                    print('\033[34;1m臥槽,碉堡了,土豪,咱們朋友吧~\033[0m')
                                print('-'*50)
                                if input('按下任意鍵繼續...'):pass
                                continue
                            else:  #若是輸入一個非y/Y值,提示用戶沒有選擇充值,然後進入商品詳單列表
                                print('抱歉,您沒有選擇充值')
                                continue
                else:
                    #print('\033[31;1m輸入數量不可用!\033[0m')
                    if input('\033[31;1m抱歉,您輸入數量的不可用!按下任意鍵繼續...\033[0m'):pass
                    continue
            if User_id2 == 'q' or User_id2 == 'Q': #輸入Q/q,退出程式
                #user_shopping[user].setdefault(user,User_salary)   #退出以前將用戶名和用於餘額信息寫入字典用於下一次登陸判斷
                user_shopping[user].setdefault('salary',User_salary)
                with open(user_shopping_db,'wb') as f:
                    #f.write(str(user_shopping.items()))
                    pickle.dump(user_shopping,f)
                print('歡迎下次再來 [ %s ], bye!'%user)
                time.sleep(1)
                Flag = True
                break
            if User_id2 == 'c' or User_id2 == 'C': #容許用戶輸入c/C查看購物車信息
                print('購物車'.center(70))
                print('-'*70)

                print('\033[34;1m序列       寶貝名            數量      小計      購買時間\033[0m') #先打印title
                product_index = 1 #定義一個序列ID
                user_consume = 0 #定義一個值爲0的用戶消費金額初始值,用於下面累加用戶這次消費總金額
                #print(user_shopping)
                for value in user_shopping[user].keys():
                    #print(value)
                    #print(shopp_car.format(product_index,index,value[1][0],value[0][1],value[0][2],))
                    print(shopp_car.format(product_index,value,user_shopping[user][value][0],user_shopping[user][value][1],user_shopping[user][value][2],))
                    user_consume += user_shopping[user][value][1] #自增用戶消費金額
                    product_index += 1 #序列ID自增
                print('-'*70)
                print('\033[34;1m親愛的用戶[ %s ], 共消費 [ %s ]元, 您的餘額 [ %s ]元\033[0m'%(user,user_consume,User_salary))

                if input('\033[32;1m 按下任意鍵繼續...\033[0m'):pass
            if User_id2 == 'b' or User_id2 == 'B':  #輸入b/B,返回上一級
                User_flag = True
                break
            else:
                #print('\033[31;1m您輸入的寶貝序列不可用!!!\033[0m')
                continue

                #pass
                #print(product1)
                #print(price)
    else:
        if not User_id:
            print('\033[31;1m您輸入的寶貝序列不可用!!!\033[0m')
            User_flag = True
            continue
        else:
            User_flag = True

若是要修改一個功能很是費勁,可若是用到函數式編程的話,代碼可讀性等等一大堆好處就來了

還沒時間重寫啦

1.函數的組成:

def f1(a,b):
    pass
    return 
    

# def  定義函數的關鍵字
# f1   函數名,能夠是任何字符串合法的字符,但不能是Python內部保留字
# a,b  參數,主要爲函數體提供數據
# ()  固定搭配
# pass  函數體
# return 返回值,默認狀況下若是不顯式指定return值的話,Python會返回爲None,這和其餘語言不太同樣;

2.返回值

定義了一個函數,在程序裏引用,因此函數應該將執行的結果返回一個參數,好讓調用者繼續執行下面的邏輯。仍是那個登錄程序的例子,能夠用漢字寫出來看看:

def 登錄函數(等待用戶傳入用戶名,密碼):
    pass
    打開文件,賦值給一個變量,而且循環遍歷文件內容
    if 若是用戶名和文件中的用戶名匹配,而且提供的密碼和文件中的密碼匹配
        #打印登錄成功
        return True  返回一個True
    若是驗證失敗
        return False

def 主函數():
    用戶輸入序列,選擇是登錄仍是註冊用戶
    若是是登錄
        提示用戶輸入用戶名\密碼
        R = 調用上面登錄函數(用戶輸入用戶名,密碼)  調用登錄函數, 並將結果複製給變量R
        if R爲True
            打印登錄成功
        else 不然
            打印用戶名密碼驗證失敗:
        
    ...
主函數()

3. 參數

函數參數的做用有多大,不用多言了吧,總之過重要了。若是沒有參數的話,函數將會變的很不靈活

函數中有幾種不一樣的參數:

   1. 普通參數

#定義一個函數f1,接受用戶傳入參數name,然後在函數體內打印用戶輸入的值。name叫作形式參數
>>> def f1(name):
...   print(name)
... 


#調用函數,並傳入一個值,這裏的值daniel叫作實際參數;
>>> f1('daniel')
daniel

   2. 默認參數

#定義一個函數f2,接受用戶輸入兩個形式參數,並給形式參數指定一個默認值
>>> def f2(name,job='devops'):
...   print(name,job)
... 


#調用函數,並使用默認參數,‘devops’
>>> f2('daniel')
daniel devops

   3. 指定參數

#定義一個函數f3,接受用戶輸入兩個形參,並給定age一個默認參數爲18
>>> def f3(name,age=18):
...   print('Name: %s, Age: %s'%(name,age))
... 
#調用參數,明確指定一個age參數爲17
>>> f3('daniel',17)
Name: daniel, Age: 17

    4. 動態參數

動態參數有兩種,一種是一個*,一種是 **

  *  默認接受N個參數,並將用戶傳入的實際參數放到元組裏面,默認狀況下都用 *args表示形參

#定義一個函數f4, 接受形參*args
>>> def f4(*args):
...   print(args)
...   print(type(args))
...   print(*args)
...   print(type(*args))
... 
#定義一個列表l1
>>> l1=[1,2,3,4,5,]
#調用函數,將l1賦值給函數
>>> f4(l1)
([1, 2, 3, 4, 5],)  #默認方式是將一個列表當作總體元素包含在元組內
<class 'tuple'>
[1, 2, 3, 4, 5]   #在函數體內打印*args是轉換成原有的數據類型
<class 'list'>

#再定義一個t1的元組,一個name的字符串,一個t2的字典
>>> t1=(5,4,3,2,1,)
>>> name=('daniel')
>>> t2 = {'k1':'v1','k2':'v2'}
#從新定義函數
>>> def f4(*args):
...   print(args)
...   print(type(args))
...   print(*args)
... 

#調用函數,並把字典、列表、元組、字符串都複製進去,看看變化
>>> f4(l1,t1,name,t2)
#默認函數體裏打印args,是把添加的任意個元組當成元組內的一個元素
([1, 2, 3, 4, 5], (5, 4, 3, 2, 1), 'daniel', {'k2': 'v2', 'k1': 'v1'})
<class 'tuple'>
#在函數體內打印*args,是將用戶傳入的實體參數還原爲原本的數據類型,即字符串就是字符串,而字典仍是字典...
[1, 2, 3, 4, 5] (5, 4, 3, 2, 1) daniel {'k2': 'v2', 'k1': 'v1'}


#還有一個玩法,能夠在調用函數傳入實體參數的時候,在前面加*
>>> f4(*l1,*t1,*name,*t2)
#這個玩法,在默認函數體內打印傳入形參值,會是遍歷傳入的參數,然後賦值給元組內
(1, 2, 3, 4, 5, 5, 4, 3, 2, 1, 'd', 'a', 'n', 'i', 'e', 'l', 'k2', 'k1')
<class 'tuple'>
#而*args是會還原原有的數據類型,去掉元組,我的感受沒卵用;
1 2 3 4 5 5 4 3 2 1 d a n i e l k2 k1
動態參數-*args

** 傳值的時候必須指定一個key和value,默認是字典類型;默認使用 **kwargs表示形參

#定義函數f5,接受用戶傳入形參**kwargs
def f5(**kwargs):
    print(kwargs)
    print(type(kwargs))

#調用函數時,第一種賦值方式
f5(Name='daniel',Age=18,Job='IT')
{'Name': 'daniel', 'Job': 'IT', 'Age': 18}
<class 'dict'>

#定義一個字典t1
t1 = {'Name':'daniel','Age':18,'Job':'IT'}
#調用函數第二種賦值方式,實在實參前面加**
f5(**t1)
{'Age': 18, 'Name': 'daniel', 'Job': 'IT'}
<class 'dict'>
動態參數-**args

   5. 萬能參數

直白來講,就是兩種動態參數的組合,須要注意的是兩種動態參數組合使用時,*必須放在第一個位置,不然會報錯

#定義函數f6,接受形參*args,**kwargs,在函數體內打印兩個值,和數據類型
def f6(*args,**kwargs):
    print(args,kwargs)
    print(type(args))
    print(type(kwargs))

#調用函數,前面是*,後面是**
f6('我是誰?','幾年幾歲?','作什麼工做?',Name='Daniel',Age=18,Job='IT')

('我是誰?', '幾年幾歲?', '作什麼工做?') {'Age': 18, 'Name': 'Daniel', 'Job': 'IT'}
<class 'tuple'>
<class 'dict'>

#也能夠這麼玩:
t1 = {'Name':'daniel','Age':18,'Job':'IT'}
f6('我是誰?','幾年幾歲?','作什麼工做?',**t1)
('我是誰?', '幾年幾歲?', '作什麼工做?') {'Name': 'daniel', 'Age': 18, 'Job': 'IT'}
<class 'tuple'>
<class 'dict'>

#嘗試下把**放在前面:
t1 = {'Name':'daniel','Age':18,'Job':'IT'}
f6(**t1,'我是誰?','幾年幾歲?','作什麼工做?')

f6(**t1,'我是誰?','幾年幾歲?','作什麼工做?')
           ^
SyntaxError: positional argument follows keyword argument unpacking
#直接報語法錯誤:

#在函數體內把**kwargs放在前面試下:
def f6(**kwargs,*args):
    print(args,kwargs)
    print(type(args))
    print(type(kwargs))

#執行仍是報錯語法錯誤
def f6(**kwargs,*args):
                   ^
SyntaxError: invalid syntax
萬能參數

三.  Python內嵌函數

內置函數主要是使用比較頻繁的或者是元操做,因此Python經過內置函數的方式提供

 

官方文檔連接,戳我

四. 文件操做

在Python3裏提供了open函數來對文件操做,Python2中有file函數 。

1. open()函數語法

使用open函數的語法:

file object = open(file_name [, access_mode][, buffering])

   file object: 文件句柄,在後面經過此句柄對該文件操做等等;

   file_name:  文件名稱,若是不在當前目錄下,須要制定絕對/相對路徑

   access_mode: 打開模式,表示容許對文件操做的權限等

   buffering:若是值爲0,就不會有寄存。若是爲1,訪問文件時會寄存。若是值設定大於1的整數,說明這就是寄存區的大小。若是取負值,寄存區的緩衝大小則爲系統默認。

2. 打開文件模式:

  • r   以只讀方式打開文件,文件指針將會放在文件開頭的位置,這也是默認的模式;
  • #以只讀模式打開文件,賦值給文件句柄f
    >>> f = open('test.txt','r')
    # 寫入數據嘗試,報錯,是隻讀的,不容許寫!
    >>> f.write('abc')
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    io.UnsupportedOperation: not writable
    # 查看文件指針位置,能夠看到在文件開頭的位置;
    >>> f.tell()
    0
    # 讀取文件內容
    >>> f.readline()
    'abc\n'
    r 只讀模式
  • w  以只寫入的方式打開文件,若是文件存在內容,會清空文件後,再打開,文件指針在開頭的位置。若是文件不存在,則建立新文件;
  • #至寫入模式
    >>> f = open('test.txt','w')
    #查看文件指針,在文件首部
    >>> f.tell()
    0
    #不容許讀
    >>> f.read()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    io.UnsupportedOperation: not readable
    #寫入文件1,2,3,會覆蓋以前文件裏的abc內容,並返回當前的文件指針位置
    >>> f.write('1,2,3')
    5
    #驗證下文件指針位置
    >>> f.tell()
    5
    #結束後必定不要忘記關閉文件
    >>> f.close()
    w 只寫模式
  • a   打開文件以追加的模式,若是該文件存在,文件指針會放到文件末尾的位置,也就是說新的內容會將被寫入到文件的末尾。若是文件不存在,建立新文件來寫入。
  • # 追加方式
    >>> f = open('test.txt','a')
    # 文件指針在文件末尾的位置,即舊內容後面
    >>> f.tell()
    5
    #讀文件報錯
    >>> f.read()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    io.UnsupportedOperation: not readable
    # 寫入文件後,返回寫入內容後指針後移的位置,並不是實際指針位置
    >>> f.write('abc')
    3
    # 查看文件指針,仍是在文件最尾部
    >>> f.tell()
    8
    # 關閉文件
    >>> f.close()
    a 追加模式
  • x   Python3裏新添加的模式,以只寫入的方式打開文件,文件內容若是存在會報錯,不然則建立新文件。通常建議,寫入時使用x而不用w;
  • # 先查看下文件test.txt裏的內容
    >>> f = open('test.txt','r')
    >>> f.read()
    '1,2,3abc'
    >>> f.close()
    # 以x模式打開文件,直接報錯文件存在,錯誤代碼17
    >>> f = open('test.txt','x')
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    FileExistsError: [Errno 17] File exists: 'test.txt'
    
    # 從新打開一個不存在的文件:
    >>> f = open('test1.txt','x')
    #指針模式在文件首部
    >>> f.tell()
    0
    # 寫入5個字符,文件指針在5的位置
    >>> f.write('abcde')
    5
    # 返回指針位置
    >>> f.tell()
    5
    # 在寫入內容123,返回指針移動位置
    >>> f.write('123')
    3
    # 返回指針位置,8
    >>> f.tell()
    8
    # 必定不要忘記關閉文件句柄
    >>> f.close()
    x 只寫模式

上面的這些模式都是要麼只讀、要麼只寫入,若是添加一個  「+」,就表示能夠同時讀寫了:

  • r+  讀寫模式打開文件,文件指針會在開頭的位置;
  • #讀寫模式
    >>> f = open('test1.txt','r+')
    # 默認文件指針在文件首部
    >>> f.tell()
    0
    # 讀取文件內容
    >>> f.read()
    'abcde123'
    #文件指針跑到文件尾部去了
    >>> f.tell()
    8
    # 寫入,就成了尾部追加了
    >>> f.write('新增長')
    3
    # 一個漢字三個三個指針
    >>> f.tell()
    17
    # 再讀取,已經空了,由於文件指針已經走到最後面了
    >>> f.read()
    ''
    # 用seek將指針調整到文件頭部
    >>> f.seek(0)
    0
    # 在讀取
    >>> f.read()
    'abcde123新增長'
    >>> f.close()
    r+ 讀寫模式
  • w+ 寫讀模式打開文件,若是文件裏有內容,就會覆蓋,不然的話,會建立新文件,使用場景仍是很少;
  • #W+模式
    >>> f = open('test1.txt','w+')
    # 默認文件句柄在文件首部
    >>> f.tell()
    0
    # 寫入文件
    >>> f.write('w+模式')
    4
    #獲取指針位置
    >>> f.tell()
    8
    #後面已經無內容了,因此爲空
    >>> f.read()
    ''
    # 重置文件指針到首部
    >>> f.seek(0)
    0
    # 讀取文件內容,看到源文件內容已經被清空了
    >>> f.read()
    'w+模式'
    >>> f.close()
    w+ 寫讀模式
  • a+  寫讀模式打開文件,若是存在,文件指針會放在文件的結尾。文件打開時會是追加模式,若是不存在會建立新的文件;
  • # a+模式
    >>> f = open('test1.txt','a+')
    # 默認文件指針在文件尾部
    >>> f.tell()
    8
    # 因此讀取爲空
    >>> f.read()
    ''
    # 寫入a+模式內容
    >>> f.write('a+模式內容')
    6
    # 返回指針位置
    >>> f.tell()
    22
    # 將指針重置到開始位置
    >>> f.seek(0)
    0
    # 讀取,能夠看到上一步w+的內容還在
    >>> f.read()
    'w+模式a+模式內容'
    >>> f.close()
    a+ 寫讀模式
  • x+  寫讀模式打開文件,
  • # x+模式,若是文件存在就會報錯文件已經存在
    >>> f = open('test1.txt','x+')
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    FileExistsError: [Errno 17] File exists: 'test1.txt'
    #打開一個不存在的文件
    >>> f = open('test2.txt','x+')
    #模式文件指針在文件首部
    >>> f.tell()
    0
    # 寫入文件內容
    >>> f.write('x+模式')
    4
    #返回文件指針
    >>> f.tell()
    8
    #在寫入
    >>> f.write('balabala')
    8
    #讀取爲空,文件指針在尾部
    >>> f.read()
    ''
    #重置指針
    >>> f.seek(0)
    0
    >>> f.read()
    'x+模式balabala'
    #關閉文件
    >>> f.close()
    x+寫讀模式

以"b"表示以二進制的方式操做,須要注意的是以"b"方式打開文件是字節類型,寫入時也須要提供本身類型,反之同樣。

  •  rb    二進制讀模式打開文件,文件指針會放在文件的開頭。
  • #先用wb模式寫入一個二進制文件
    >>> f = open('test2.txt','wb')
    #定義一箇中文字符串
    >>> s1 = '我是誰?' 
    #寫入時,使用utf-8編碼
    >>> f.write(s1.encode('utf-8'))
    10
    >>> f.tell()
    10
    #關閉文件
    >>> f.close()
    #用rb模式打開一個文件
    >>> f = open('test2.txt','rb')
    #試着用默認編碼讀取,看到是b(二進制格式)
    >>> f.read()
    b'\xe6\x88\x91\xe6\x98\xaf\xe8\xb0\x81?'
    >>> f.tell()
    10
    #重置指針到文件首部
    >>> f.seek(0)
    0
    # 將f.read() 複製給一個變量
    >>> r = f.read()
    # 然後使用decode將字符編碼使用utf-8
    >>> print(r.decode('utf-8'))
    我是誰?
    >>> f.close()
    rb 二進只讀模式
  •  rb+  二進制只讀模式打開文件,文件指針會放在文件的開頭。
  • # rb+模式
    >>> f = open('test2.txt','rb+')
    >>> s = '巴拉巴阿'
    # 文件指針在文件首部
    >>> f.tell()
    0
    #寫入內容,並使用utf-8編碼
    >>> f.write(s.encode('utf-8'))
    12
    # 返回文件指針
    >>> f.tell()
    12
    # 重置指針
    >>> f.seek(0)
    0
    >>> s = f.read()
    # 使用decode utf-8 編碼讀取文件
    >>> print(s.decode('utf-8'))
    巴拉巴阿
    
    >>> f.tell()
    12
    >>> f.seek(0)
    0
    #  直接讀取顯示沒法顯示
    >>> f.read()
    b'\xe5\xb7\xb4\xe6\x8b\x89\xe5\xb7\xb4\xe9\x98\xbf'
    rb+ 讀寫二進制模式
  •  wb   二進制的只寫模式打開文件,若是文件存在會清空文件,不然建立新文件。
  • #用wb模式寫入一個二進制文件
    >>> f = open('test2.txt','wb')
    #文件指針默認在文件首部,會清空原有文件
    >>> f.tell()
    0
    #定義一箇中文字符串
    >>> s1 = '我是誰?' 
    #寫入時,使用utf-8編碼
    >>> f.write(s1.encode('utf-8'))
    10
    >>> f.tell()
    10
    #關閉文件
    >>> f.close()
    wb 二進只寫模式
  •  wb+  二進制寫讀模式,若是文件存在會覆蓋文件,不然會建立新文件。
  • # wb+模式仍是會清空文件
    >>> f = open('test2.txt','wb+')
    # 默認文件指針位置在首部
    >>> f.tell()
    0
    >>> s = f.read()
    >>> print(s.decode('utf-8'))
    
    >>> s1 = '這模式怎麼又清空文件啦?'
    >>> f.write(s1.encode('utf-8'))
    36
    >>> f.tell()
    36
    >>> f.seek(0)
    0
    >>> s = f.read()
    >>> print(s.decode('utf-8'))
    這模式怎麼又清空文件啦?
    >>> f.close()
    wb+ 二進制寫讀模式
  •  xb    二進制只寫,若是文件存在報錯?不然建立新文件?
  • # 文件存在仍是會報錯
    >>> f = open('test2.txt','xb')
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    FileExistsError: [Errno 17] File exists: 'test2.txt'
    # 若是不存在的話,操做和wb同樣
    >>> f = open('test2.txt','xb')
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    FileExistsError: [Errno 17] File exists: 'test2.txt'
    >>> f = open('test3.txt','xb')
    >>> s = '這是xb二進制只寫入模式,是python3新增'
    >>> f.tell()
    0
    >>> f.write(s.encode('utf-8'))
    51
    >>> f.tell()
    51
    >>> f.seek(0)
    0
    # 不容許讀取
    >>> f.read()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    io.UnsupportedOperation: read
    >>> f.close()
    xb 二進制只寫模式
  •  xb+  二進制寫讀模式打開文件,若是存在覆蓋,不然建立新文件。
  • # 若是存在文件,會報錯
    >>> f = open('test3.txt','xb+')
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    FileExistsError: [Errno 17] File exists: 'test3.txt'
    
    >>> f = open('test4.txt','xb+')
    >>> f.tell()
    0
    >>> s = '這是xb+二進制寫讀模式,是python3新增特性'
    # 可寫入
    >>> f.write(s.encode('utf-8'))
    55
    # 也可讀寫
    >>> s1 = f.read()
    >>> print(s1.decode('utf-8'))
    這是xb+二進制寫讀模式,是python3新增特性
    >>> f.close()
    xb+ 二進制寫讀模式
  •  ab    二進制追加模式打開文件,若是存在文件,文件指針在末尾,文件打開時會是追加模式,新內容在舊內容以後,若是文件不存在,建立新文件來寫入。
  • # ab,二進制只寫模式
    >>> f = open('test4.txt','ab')
    # 默認文件指針在文件尾部
    >>> f.tell()
    55
    # 不容許讀
    >>> f.read()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    io.UnsupportedOperation: read
    >>> s = '\n這是ab模式輸入的內容'
    # 在文件尾部添加內容
    >>> f.write(s.encode('utf-8'))
    30
    # 關閉文件
    >>> f.close()
    ab 二進制只寫模式
  •  ab+  二進制寫讀模式打開,若是存在文件,文件指針在末尾,若是不存在,建立新文件。
  • >>> f = open('test4.txt','ab+')
    >>> f.tell()
    85
    >>> s = '\n這是ab+添加的內容'
    >>> f.write(s.encode('utf-8'))
    25
    >>> f.tell()
    110
    >>> f.seek(0)
    0
    #也可使用for循環逐行讀取,並複製給s,然後使用decode進行解碼
    >>> for line in f:
    ...   s = line
    ...   print(s)
    ... 
    b'\xe8\xbf\x99\xe6\x98\xafxb+\xe4\xba\x8c\xe8\xbf\x9b\xe5\x88\xb6\xe5\x86\x99\xe8\xaf\xbb\xe6\xa8\xa1\xe5\xbc\x8f\xef\xbc\x8c\xe6\x98\xafpython3\xe6\x96\xb0\xe5\xa2\x9e\xe7\x89\xb9\xe6\x80\xa7\n'
    b'\xe8\xbf\x99\xe6\x98\xafab\xe6\xa8\xa1\xe5\xbc\x8f\xe8\xbe\x93\xe5\x85\xa5\xe7\x9a\x84\xe5\x86\x85\xe5\xae\xb9\n'
    b'\xe8\xbf\x99\xe6\x98\xafab+\xe6\xb7\xbb\xe5\x8a\xa0\xe7\x9a\x84\xe5\x86\x85\xe5\xae\xb9'
    >>> f.seek(0)
    0
    >>> for line in f:
    ...   s = line
    ...   print(line.decode('utf-8').strip())
    ... 
    這是xb+二進制寫讀模式,是python3新增特性
    這是ab模式輸入的內容
    這是ab+添加的內容
    ab+ 二進制寫讀模式

     

  3. 操做方法

還記得上面的每次打開文件後都須要close()吧,一個文件被打開後,可使用方法來查看各類文件的信息

closed  若是返回爲True表示文件已關閉,不然爲False

>>> f.closed
False
>>> f.close()
>>> f.closed
True

mode  查看文件打開的模式

>>> f = open('test4.txt','ab+')
>>> f.mode
'ab+'

name 文件名

>>> f.name
'test4.txt'
View Code

raw 查看文件句柄詳細信息

>>> f.raw
<_io.FileIO name='test4.txt' mode='ab+'>

encoding 查看編碼

>>> f.encoding
'UTF-8'
View Code

close  關閉文件句柄

>>> f.close()

read  讀取指定字節數據,若是不指定值,則返回整個文件內容

>>> f.read()
'1,2,3abc'
>>> f.read(3)
'1,2'
View Code

readline 僅讀取一行數據,能夠指定讀取的字節數

# 文件內容三行
>>> f.read()
'1,2,3abc\nABC\nDEF'
>>> f.seek(0)
0
# 一次只讀取一行內容
>>> f.readline()
'1,2,3abc\n'
>>> f.tell()
9
>>> f.seek(0)
0
# 能夠指定讀取的字節數
>>> f.readline(3)
'1,2'
View Code

readlines  讀取全部數據,並根據換行符保存內容至列表

>>> f.seek(0)
0
# 所有放在列表中
>>> f.readlines()
['1,2,3abc\n', 'ABC\n', 'DEF']
>>> f.seek(0)
0
#對列表可作進一步操做
>>> f.readlines()[0]
'1,2,3abc\n'
View Code

readable  文件是否可讀,可讀返回True,不然返回False

>>> f = open('test.txt','r+')
>>> f.readable()
True
>>> f.close()
>>> f = open('test.txt','a')
>>> f.readable()
False
View Code

write 寫內容(字符串)

>>> f.write('balbalbalallla')
14
>>> f.seek(0)
0
>>> f.read()
'1,2,3abc\nABC\nDEFbalbalbalallla'
View Code

writelines  寫內容,(列表)

#寫入字符串,也OK
>>> f.writelines('這是啥我也不知道')
>>> f.tell()
54
>>> f.read()
''
>>> f.seek(0)
0
>>> f.read()

'1,2,3abc\nABC\nDEFbalbalbalallla這是啥我也不知道'
# write寫字符串也ok
>>> s1 = 'daniel'
>>> f.write(s1)
6
>>> f.writelines(s1)
>>> f.seek(0)
0
>>> f.read()
'1,2,3abc\nABC\nDEFbalbalbalallla這是啥我也不知道danieldaniel'
#來試下列表
>>> l1 = ['i','am','is','supperman']
# write失敗
>>> f.write(l1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: must be str, not list
# writelines沒問題
>>> f.writelines(l1)
>>> f.seek(0)
0
>>> f.readlines()
['1,2,3abc\n', 'ABC\n', 'DEFbalbalbalallla這是啥我也不知道danieldanieliamissupperman']
>>> f.seek(0)
0
>>> f.read()
'1,2,3abc\nABC\nDEFbalbalbalallla這是啥我也不知道danieldanieliamissupperman'

#來試下元組
>>> t1 = ('a','b','c','d')
>>> f.write(t1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: must be str, not tuple
# writelines 是ok的
>>> f.writelines(t1)
>>> f.seek(0)
0
>>> f.read()
'1,2,3abc\nABC\nDEFbalbalbalallla這是啥我也不知道danieldanieliamissuppermanabcd'

#測試下字典
>>> d1 = {'k1':'v1','k2':'v2'}
>>> f.write(d1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: must be str, not dict
# writelines 仍是ok的
>>> f.writelines(d1)
>>> f.seek(0)
0
>>> f.read()
'1,2,3abc\nABC\nDEFbalbalbalallla這是啥我也不知道danieldanieliamissuppermanabcdk1k2'
View Code

writable 是否可寫,可寫返回True,不然返回False

>>> f.writable()
True
View Code

tell  返回當前指針位置

>>> f.tell()
0
View Code

seek 移動指針位置

>>> f.read()
'1,2,3abc\nABC\nDEF'
>>> f.seek(3)
3
>>> f.read()
',3abc\nABC\nDEF'
View Code

seekable 指針是否可讀,是: True, 否:False, Python3新增

>>> f.seekable()
True
View Code

fileno  返回一個文件的文件描述符,能夠用在os模塊的read方法等一些底層的操做

>>> f.fileno()
3
View Code

isatty  判斷文件是否鏈接在一個終端設備,是:true,否:False

>>> f.isatty()
False
View Code

truncate  截斷文件,截取的字節經過參數提供,默認爲當前指針位置

>>> f.tell()
0
#看下全部文件內容
>>> f.read()
'1,2,3abc\nABC\nDEFbalbalbalallla這是啥我也不知道danieldanieliamissuppermanabcdk1k2'
#再把指針指向開始位置
>>> f.seek(0)
0
# 截取三個字符
>>> f.truncate(3)
3
#查看文件指針
>>> f.tell()
0
# 查看文件
>>> f.read()
'1,2'
>>> f.read()
''
>>> f.seek(0)
0
>>> f.read()
'1,2'
>>> f.seek(0)
0
#若是不提供參數,從當前默認的指針位置開始截取,當前爲開始位置,因此清空文件內容
>>> f.truncate()
0
>>> f.read()
''
>>> f.seek(0)
0
>>> f.read()
View Code

flush  刷寫文件內部緩存,直接把緩衝區的數據當即寫入文件,而不是被動的等待緩衝區寫入。

>>> f.flush()
View Code
 buffer = property(lambda self: object(), lambda self, v: None, lambda self: None)  # default

    closed = property(lambda self: object(), lambda self, v: None, lambda self: None)  # default

    encoding = property(lambda self: object(), lambda self, v: None, lambda self: None)  # default

    errors = property(lambda self: object(), lambda self, v: None, lambda self: None)  # default

    line_buffering = property(lambda self: object(), lambda self, v: None, lambda self: None)  # default

    name = property(lambda self: object(), lambda self, v: None, lambda self: None)  # default

    newlines = property(lambda self: object(), lambda self, v: None, lambda self: None)  # default

    _CHUNK_SIZE = property(lambda self: object(), lambda self, v: None, lambda self: None)  # default

    _finalizing = property(lambda self: object(), lambda self, v: None, lambda self: None)  # default
View Code

4. 管理上下文

上面的文件操做,打開操做完成以後每次都須要關閉文件,爲了不忘記,能夠經過(with)管理上下文:

with open('test.txt','r+') as f:    #打開test.txt文件以r+模式,並別名爲f,操做完成後內部會自動關閉並釋放文件資源
    pass

另外在python2.7之後,with也支持同事打開兩個文件來操做:

with open('test.txt','r') as f1, open('test2.txt','w') as f2:   
     pass

 

五. 三元運算

三元運算又叫三目運算,主要是一些簡單if else語句的縮寫;先寫判斷條件 然後進入判斷 最後條件不知足的操做:

>>> a = 1
>>> print('這是條件爲真打印的結果') if a == 1 else '這是條件爲假打印的結果'
這是條件爲真打印的結果
>>> a = 0
>>> print('這是條件爲真打印的結果') if a == 1 else '這是條件爲假打印的結果'
這是條件爲假打印的結果
>>> a = 1 if b != 3 else 4
>>> a
4
# 若是條件成立那麼 a = 1 ,不然 a = 4

六. lambda表達式

Python lambda 實在python中使用lambda來建立匿名函數,而用def建立的方法是有函數名稱的。看看lambda的精簡格式吧:

lambda args: print(args)
#一個參數
>>> info = lambda a: a**3
>>> type(info)
<class 'function'>
>>> info(2)
8
>>> info(4)
64

#兩個參數
>>> m = lambda a,b: a*b
>>> m(2,3)
6
>>> m(19,13)
247

#三個參數
>>> m = lambda x,y,z: (x-y)*z
>>> m(3,2,1)
1
>>> m(3,2,2)
2
>>> m(3,2,3)
3
>>> m(3,3,3)
0
>>> m(3,22,3)
-57
View Code

七. 全局變量

全局變量遵循名稱所有大寫的規範,即:

NAME = 'daniel'
AGE = 18
JOB = 'IT'

全局變量在全部的做用域均可以讀;


NAME = {'Name':'Daniel'} def f1(): age = 18 print(NAME,age) print(id(NAME)) def f2(): age = 19 print(NAME,age) print(id(NAME)) def f3(): age = 17 print(NAME,age) print(id(NAME)) f1() f2() f3()

全局變量能夠在函數裏可讀,也能夠寫,可是更改要在函數裏使用global聲明,不過不建議這麼作!

#全局變量

NAME = {'Name':'Daniel'}


def f1():
    age = 18
    print(NAME,age)
    print(id(NAME))

def f2():
    age = 19
    NAME='F2'
    print(NAME,age)
    print(id(NAME))
def f3():
    age = 17
    print(NAME,age)
    print(id(NAME))

f1()
f2()
f3()

執行結果,在f2函數是修改了NAME值,可是這只是一個名字叫NAME的一個局部變量而已;
{'Name': 'Daniel'} 18
4321829832
F2 19
4323767664
{'Name': 'Daniel'} 17
4321829832
View Code
NAME = {'Name':'Daniel'}


def f1():
    age = 18
    print(NAME,age)
    print(id(NAME))

def f2():
    age = 19
    global NAME
    NAME='F2'
    print(NAME,age)
    print(id(NAME))
def f3():
    age = 17
    print(NAME,age)
    print(id(NAME))

f1()
f2()
f3()

#執行結果
{'Name': 'Daniel'} 18
4321829832
F2 19
4323767664
F2 17
4323767664
global後再修改

全局變量若是是列表類型,在函數裏能夠增、刪、修改,可是不能從新賦值,不然將會從新開闢一個內存地址,在函數裏定義了一個同名的局部變量而已。

#NAME = {'Name':'Daniel'}
NAME=['a','b','c',]


def f1():
    age = 18
    print(NAME,age)
    print(id(NAME))

def f2():
    age = 19
    NAME[1] = 'B'
    del NAME[0]
    NAME.append('D')
    print(NAME,age)
    print(id(NAME))
def f3():
    age = 17
    print(NAME,age)
    print(id(NAME))

f1()
f2()
f3()

#執行結果
['a', 'b', 'c'] 18
4315828296
['B', 'c', 'D'] 19
4315828296
['B', 'c', 'D'] 17
4315828296
能夠修改,但不能從新賦值

在python中,strings, tuple, 和number 是不可更改的對象,而list,dict等則是能夠修改的對象。

Python中全部的參數(自變量)在python裏都是按引用傳遞的,若是在函數裏修改了參數,那麼在調用這個參數的函數裏,原始的參數也就改變了。

l1 = [10,20,30]

def f1(value):
    value.append([1,2,3,4,5,])
    print('函數內的引用值: %s' %value)

f1(l1)
print('函數外列表值: %s' %l1)

#執行結果:
函數內的引用值: [10, 20, 30, [1, 2, 3, 4, 5]]
函數外列表值: [10, 20, 30, [1, 2, 3, 4, 5]]

傳入的函數和在末尾追加的內容是同一個引用,因此結果是同樣的。

相關文章
相關標籤/搜索