日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

字符编码和函数

發布時間:2023/12/18 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 字符编码和函数 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

字符編碼的只是儲配

?1. 文本編輯器存取文件的原理(nodepad++,pycharm,word)

    打開編輯器就打開了啟動了一個進程,是在內存中的,所以在編輯器編寫的內容也都是存放與內存中的,斷電后數據丟失

? ? ? ? ? ? ?因而需要保存到硬盤上,點擊保存按鈕,就從內存中把數據刷到了硬盤上。

? ? ? ? ? ? ?在這一點上,我們編寫一個py文件(沒有執行),跟編寫其他文件沒有任何區別,都只是在編寫一堆字符而已。

? ? ??2. python解釋器執行py文件的原理 ,例如python test.py

    第一階段:python解釋器啟動,此時就相當于啟動了一個文本編輯器

    第二階段:python解釋器相當于文本編輯器,去打開test.py文件,從硬盤上將test.py的文件內容讀入到內存中

    第三階段:python解釋器解釋執行剛剛加載到內存中test.py的代碼

  總結:

  • python解釋器是解釋執行文件內容的,因而python解釋器具備讀py文件的功能,這一點與文本編輯器一樣
  • 與文本編輯器不一樣的地方在于,python解釋器不僅可以讀文件內容,還可以執行文件內容
  • ?二 什么是字符編碼

    ??????計算機要想工作必須通電,也就是說‘電’驅使計算機干活,而‘電’的特性,就是高低電平(高低平即二進制數1,低電平即二進制數0),也就是說計算機只認識數字

      編程的目的是讓計算機干活,而編程的結果說白了只是一堆字符,也就是說我們編程最終要實現的是:一堆字符驅動計算機干活

      所以必須經過一個過程:

      字符--------(翻譯過程)------->數字?

      這個過程實際就是一個字符如何對應一個特定數字的標準,這個標準稱之為字符編碼

    三 字符編碼的發展史

    階段一:現代計算機起源于美國,最早誕生也是基于英文考慮的ASCII

      ASCII:一個Bytes代表一個字符(英文字符/鍵盤上的所有其他字符),1Bytes=8bit,8bit可以表示0-2**8-1種變化,即可以表示256個字符

        ASCII最初只用了后七位,127個數字,已經完全能夠代表鍵盤上所有的字符了(英文字符/鍵盤的所有其他字符)

        后來為了將拉丁文也編碼進了ASCII表,將最高位也占用了

    階段二:為了滿足中文,中國人定制了GBK

      GBK:2Bytes代表一個字符

      為了滿足其他國家,各個國家紛紛定制了自己的編碼

      日本把日文編到Shift_JIS里,韓國把韓文編到Euc-kr里

    階段三:各國有各國的標準,就會不可避免地出現沖突,結果就是,在多語言混合的文本中,顯示出來會有亂碼。

    于是產生了unicode, 統一用2Bytes代表一個字符, 2**16-1=65535,可代表6萬多個字符,因而兼容萬國語言

    但對于通篇都是英文的文本來說,這種編碼方式無疑是多了一倍的存儲空間(二進制最終都是以電或者磁的方式存儲到存儲介質中的)

    于是產生了UTF-8,對英文字符只用1Bytes表示,對中文字符用3Bytes

    需要強調的一點是:

    unicode:簡單粗暴,所有字符都是2Bytes,優點是字符->數字的轉換速度快,缺點是占用空間大

    utf-8:精準,對不同的字符用不同的長度表示,優點是節省空間,缺點是:字符->數字的轉換速度慢,因為每次都需要計算出字符需要多長的Bytes才能夠準確表示  

  • 內存中使用的編碼是unicode,用空間換時間(程序都需要加載到內存才能運行,因而內存應該是盡可能的保證快)
  • 硬盤中或者網絡傳輸用utf-8,網絡I/O延遲或磁盤I/O延遲要遠大與utf-8的轉換延遲,而且I/O應該是盡可能地節省帶寬,保證數據傳輸的穩定性。
  • ????所有程序,最終都要加載到內存,程序保存到硬盤不同的國家用不同的編碼格式,但是到內存中我們為了兼容萬國(計算機可以運行任何國家的程序原因在于此),統一且固定使用unicode,這就是為何內存固定用unicode的原因,你可能會說兼容萬國我可以用utf-8啊,可以,完全可以正常工作,之所以不用肯定是unicode比utf-8更高效啊(uicode固定用2個字節編碼,utf-8則需要計算),但是unicode更浪費空間,沒錯,這就是用空間換時間的一種做法,而存放到硬盤,或者網絡傳輸,都需要把unicode轉成utf-8,因為數據的傳輸,追求的是穩定,高效,數據量越小數據傳輸就越靠譜,于是都轉成utf-8格式的,而不是unicode。

    ?四? 字符編碼的發展史

    ??? 計算機由美國人發明,最早的字符編碼為ASCII,只規定了英文字母數字和一些特殊字符與數字的對應關系。最多只能用 8 位來表示(一個字節),即:2**8 = 256,所以,ASCII碼最多只能表示 256 個符號

    ??

    當然我們編程語言都用英文沒問題,ASCII夠用,但是在處理數據時,不同的國家有不同的語言,日本人會在自己的程序中加入日文,中國人會加入中文。

    而要表示中文,單拿一個字節表表示一個漢子,是不可能表達完的(連小學生都認識兩千多個漢字),解決方法只有一個,就是一個字節用>8位2進制代表,位數越多,代表的變化就多,這樣,就可以盡可能多的表達出不通的漢字

    所以中國人規定了自己的標準gb2312編碼,規定了包含中文在內的字符->數字的對應關系。

    日本人規定了自己的Shift_JIS編碼

    韓國人規定了自己的Euc-kr編碼(另外,韓國人說,計算機是他們發明的,要求世界統一用韓國編碼)

    這時候問題出現了,精通18國語言的小周同學謙虛的用8國語言寫了一篇文檔,那么這篇文檔,按照哪國的標準,都會出現亂碼(因為此刻的各種標準都只是規定了自己國家的文字在內的字符跟數字的對應關系,如果單純采用一種國家的編碼格式,那么其余國家語言的文字在解析時就會出現亂碼)

    所以迫切需要一個世界的標準(能包含全世界的語言)于是unicode應運而生(韓國人表示不服,然后沒有什么卵用)

    ascii用1個字節(8位二進制)代表一個字符

    unicode常用2個字節(16位二進制)代表一個字符,生僻字需要用4個字節

    例:

    字母x,用ascii表示是十進制的120,二進制0111 1000

    漢字中已經超出了ASCII編碼的范圍,用Unicode編碼是十進制的20013,二進制的01001110 00101101。

    字母x,用unicode表示二進制0000 0000 0111 1000,所以unicode兼容ascii,也兼容萬國,是世界的標準

    這時候亂碼問題消失了,所有的文檔我們都使用但是新問題出現了,如果我們的文檔通篇都是英文,你用unicode會比ascii耗費多一倍的空間,在存儲和傳輸上十分的低效

    本著節約的精神,又出現了把Unicode編碼轉化為“可變長編碼”的UTF-8編碼。UTF-8編碼把一個Unicode字符根據不同的數字大小編碼成1-6個字節,常用的英文字母被編碼成1個字節,漢字通常是3個字節,只有很生僻的字符才會被編碼成4-6個字節。如果你要傳輸的文本包含大量英文字符,用UTF-8編碼就能節省空間:

    字符ASCIIUnicodeUTF-8
    A0100000100000000 0100000101000001
    x01001110 0010110111100100 10111000 10101101

    從上面的表格還可以發現,UTF-8編碼有一個額外的好處,就是ASCII編碼實際上可以被看成是UTF-8編碼的一部分,所以,大量只支持ASCII編碼的歷史遺留軟件可以在UTF-8編碼下繼續工作。

    五? 字符編碼的使用

    ? 1 文本編輯器

    2? 文本編輯器nodpad++

    分析過程?什么是亂碼

    文件從內存刷到硬盤的操作簡稱存文件

    文件從硬盤讀到內存的操作簡稱讀文件

    亂碼一:存文件時就已經亂碼

    存文件時,由于文件內有各個國家的文字,我們單以shiftjis去存,

    本質上其他國家的文字由于在shiftjis中沒有找到對應關系而導致存儲失敗,用open函數的write可以測試,f=open('a.txt','w',encodig='shift_jis')

    f.write('你瞅啥\n何を見て\n') #'你瞅啥'因為在shiftjis中沒有找到對應關系而無法保存成功,只存'何を見て\n'可以成功

    但當我們用文件編輯器去存的時候,編輯器會幫我們做轉換,保證中文也能用shiftjis存儲(硬存,必然亂碼),這就導致了,存文件階段就已經發生亂碼

    此時當我們用shiftjis打開文件時,日文可以正常顯示,而中文則亂碼了

    再或者,存文件時:

    f=open('a.txt','wb')f.write('何を見て\n'.encode('shift_jis')) f.write('你愁啥\n'.encode('gbk')) f.write('你愁啥\n'.encode('utf-8')) f.close()

    以任何編碼打開文件a.txt都會出現其余兩個無法正常顯示的問題

    亂碼二:存文件時不亂碼而讀文件時亂碼

    存文件時用utf-8編碼,保證兼容萬國,不會亂碼,而讀文件時選擇了錯誤的解碼方式,比如gbk,則在讀階段發生亂碼,讀階段發生亂碼是可以解決的,選對正確的解碼方式就ok了,而存文件時亂碼,則是一種數據的損壞。

    3 文本編輯器pycharm

    以gbk格式保存以utf-8格式打開

    分析過程?

    總結:

    無論是何種編輯器,要防止文件出現亂碼(請一定注意,存放一段代碼的文件也僅僅只是一個普通文件而已,此處指的是文件沒有執行前,我們打開文件時出現的亂碼)

    核心法則就是,文件以什么編碼保存的,就以什么編碼方式打開

    4 程序的執行

    階段一:啟動python解釋器

    階段二:python解釋器此時就是一個文本編輯器,負責打開文件test.py,即從硬盤中讀取test.py的內容到內存中

    此時,python解釋器會讀取test.py的第一行內容,#coding:utf-8,來決定以什么編碼格式來讀入內存,這一行就是來設定python解釋器這個軟件的編碼使用的編碼格式這個編碼,

    可以用sys.getdefaultencoding()查看,如果不在python文件指定頭信息#-*-coding:utf-8-*-,那就使用默認的

    python2中默認使用ascii,python3中默認使用utf-8

    ?

    ?

    階段三:讀取已經加載到內存的代碼(unicode編碼的二進制),然后執行,執行過程中可能會開辟新的內存空間,比如x="egon"

    內存的編碼使用unicode,不代表內存中全都是unicode編碼的二進制,

    在程序執行之前,內存中確實都是unicode編碼的二進制,比如從文件中讀取了一行x="egon",其中的x,等號,引號,地位都一樣,都是普通字符而已,都是以unicode編碼的二進制形式存放與內存中的

    但是程序在執行過程中,會申請內存(與程序代碼所存在的內存是倆個空間),可以存放任意編碼格式的數據,比如x="egon",會被python解釋器識別為字符串,會申請內存空間來存放"hello",然后讓x指向該內存地址,此時新申請的該內存地址保存也是unicode編碼的egon,如果代碼換成x="egon".encode('utf-8'),那么新申請的內存空間里存放的就是utf-8編碼的字符串egon了

    針對python3如下圖

    瀏覽網頁的時候,服務器會把動態生成的Unicode內容轉換為UTF-8再傳輸到瀏覽器

    ?

    如果服務端encode的編碼格式是utf-8, 客戶端內存中收到的也是utf-8編碼的二進制。

    ?

    ?5 在python2中有兩種字符串類型str和unicode

    str類型

    當python解釋器執行到產生字符串的代碼時(例如s='方'),會申請新的內存地址,然后將'方'encode成文件開頭指定的編碼格式,這已經是encode之后的結果了,所以s只能decode

    1 #_*_coding:gbk_*_ 2 #!/usr/bin/env python 3 4 s='方'
    5 print s.encode('gbk')
    6 print s.decode('gbk')

    所以很重要的一點是:

    在python2中,str就是編碼后的結果bytes,str=bytes,所以在python2中,unicode字符編碼的結果是str/bytes

    #coding:utf-8 s='方' #在執行時,'方'會被以conding:utf-8的形式保存到新的內存空間中print repr(s) #'\xe6\x9e\x97' 三個Bytes,證明確實是utf-8 print type(s) #<type 'str'>s.decode('utf-8')
    # s.encode('utf-8') #報錯,s為編碼后的結果bytes,所以只能decode

    unicode類型

    當python解釋器執行到產生字符串的代碼時(例如s=u'林'),會申請新的內存地址,然后將'林'以unicode的格式存放到新的內存空間中,所以s只能encode,不能decode

    s=u'林' print repr(s) #u'\u6797' print type(s) #<type 'unicode'>
    # s.decode('utf-8') #報錯,s為unicode,所以只能encode s.encode('utf-8')

    打印到終端

    對于print需要特別說明的是:

    當程序執行時,比如

    x='林'

    print(x) #這一步是將x指向的那塊新的內存空間(非代碼所在的內存空間)中的內存,打印到終端,而終端仍然是運行于內存中的,所以這打印可以理解為從內存打印到內存,即內存->內存,unicode->unicode

    對于unicode格式的數據來說,無論怎么打印,都不會亂碼

    ?

    6? python3中的字符串與python2中的u'字符串',都是unicode,所以無論如何打印都不會亂碼

    在pycharm中

    在windows終端

    ?

    但是在python2中存在另外一種非unicode的字符串,此時,print x,會按照終端的編碼執行x.decode('終端編碼'),變成unicode后,再打印,此時終端編碼若與文件開頭指定的編碼不一致,亂碼就產生了

    在pycharm中(終端編碼為utf-8,文件編碼為utf-8,不會亂碼)

    ?

    在windows終端(終端編碼為gbk,文件編碼為utf-8,亂碼產生)

    ?

    思考題:

    分別驗證在pycharm中和cmd中下述的打印結果

    #coding:utf-8 s=u'林' #當程序執行時,'林'會被以unicode形式保存新的內存空間中#s指向的是unicode,因而可以編碼成任意格式,都不會報encode錯誤 s1=s.encode('utf-8') s2=s.encode('gbk') print s1 #打印正常否? print s2 #打印正常否print repr(s) #u'\u6797' print repr(s1) #'\xe6\x9e\x97' 編碼一個漢字utf-8用3Bytes print repr(s2) #'\xc1\xd6' 編碼一個漢字gbk用2Bytesprint type(s) #<type 'unicode'> print type(s1) #<type 'str'> print type(s2) #<type 'str'>

    ?7?在python三種也有兩種字符串類型str和bytes

    str是unicode

    #coding:utf-8 s='林' #當程序執行時,無需加u,'林'也會被以unicode形式保存新的內存空間中,#s可以直接encode成任意編碼格式 s.encode('utf-8') s.encode('gbk')print(type(s)) #<class 'str'>

    bytes是bytes

    #coding:utf-8 s='林' #當程序執行時,無需加u,'林'也會被以unicode形式保存新的內存空間中,#s可以直接encode成任意編碼格式 s1=s.encode('utf-8') s2=s.encode('gbk')print(s) #林 print(s1) #b'\xe6\x9e\x97' 在python3中,是什么就打印什么 print(s2) #b'\xc1\xd6' 同上print(type(s)) #<class 'str'> print(type(s1)) #<class 'bytes'> print(type(s2)) #<class 'bytes'>

    一 定義1個函數

    初中數學函數定義:一般的,在一個變化過程中,如果有兩個變量x和y,并且對于x的每一個確定的值,y都有唯一確定的值與其對應,那么我們就把x稱為自變量,把y稱為因變量,y是x的函數。自變量x的取值范圍叫做這個函數的定義域

    例如y=2*x

    python中函數定義:函數是邏輯結構化和過程化的一種編程方法。

    1 python中函數定義方法:2 3 def test(x):4 "The function definitions"5 x+=16 return x7 8 def:定義函數的關鍵字9 test:函數名 10 ():內可定義形參 11 "":文檔描述(非必要,但是強烈建議為你的函數添加描述信息) 12 x+=1:泛指代碼塊或程序處理邏輯 13 return:定義返回值


    調用運行:可以帶參數也可以不帶
    函數名()

     無參函數的定義方法,就是def 后面加上函數名,函數名后面必須要有一個括號

      格式:def 函數名():

          函數體(也就是函數的功能)

    def aa():return 11 a=aa() print(a)def bb():print(111) bb()

    ?

     有參函數的定義方法:def后面加上函數名,函數名的后面括號里傳入一個參數。

      格式:def 函數名(參數): ? (參數可以時任意的數據類型)

          函數體(函數的功能)

    def aa(a,b):return a,b bb=aa(1,2) print(bb)def cc(c,d):pass cc(1,2)

    二 函數的參數

     在定義的階段傳入的參數,就叫做形式參數,簡稱形參,形參相當于一個變量名

     在調用階段傳傳入的參數,就叫做實在參數,簡稱實參,實參相當于一個變量名的值

    def aa(a): #a就是一個形參return a bb=aa(5) #5 就是一個實參 print(bb)

    注意:在定義 階段時可以傳人多個參數,但是在定義階段傳入幾個形參(*)星號除外,在調用階段就傳入幾個形參。

    三 函數里面的return

     return:返回內容,也可以當終止符使用,一個函數只要遇見了return,執行完return,就會終止。

    def aa():print(123)returnprint(456) bb=aa() print(bb)

     調用時返回none的現象:1 直接返回的時None

                 2 沒有return這個關鍵字

                 3 返回的內容為空

    def aa():pass a=aa() print(a)def bb():return b=bb() print(b)def cc():return None c=cc() print(c)

     return可以返回多個內容,每個內容之間用逗號隔開,在調用時返回的值會以一個元組的格式返回。返回的值可以為任意的內容

    def aa():return 1,[2],'3',{4},(5),{6:7} a=aa() print(a)

     接收返回值:

      一個值接收,直到調用時遇見第一個return,就會返回第一個return返回的內容,然后終止這個函數

    def aa(x):return xreturn x+x a=aa(1) print(a)

      多個值接受,返回的變量有幾個,就要用幾個值去接收返回的內容。

    def bb(x,y,z):return x,y,z b=bb(2,5,0) print(b)

     函數里如果有print()打印,直接可以用函數名后面跟上一個括號去執行這個函數,如果在定義時函數傳入了參數,在執行的時候也要傳入相對應個數的參數值。

    def a():print(123) a()def b(x,y):print(x,y) b(3,4)

    ?

    補充:

    ?? (1).編程語言中的函數與數學意義的函數是截然不同的倆個概念,編程語言中的函數是通過一個函數名封裝好一串用來完成某一特定功能的邏輯,數學定義的函數就是一個等式,等式在傳入因變量值x不同會得到一個結果y,這一點與編程語言中類似(也是傳入一個參數,得到一個返回值),不同的是數學意義的函數,傳入值相同,得到的結果必然相同且沒有任何變量的修改(不修改狀態),而編程語言中的函數傳入的參數相同返回值可不一定相同且可以修改其他的全局變量值(因為一個函數a的執行可能依賴于另外一個函數b的結果,b可能得到不同結果,那即便是你給a傳入相同的參數,那么a得到的結果也肯定不同)

    ??? (2).函數式編程就是:先定義一個數學函數(數學建模),然后按照這個數學模型用編程語言去實現它。至于具體如何實現和這么做的好處,且看后續的函數式編程。

    執行時不依賴與外部調用者傳入的的參數就能執行。定義為無參函數

    函數的執行依賴于調用者傳入的參數才能執行時定義為有參函數。

    ?2 為何使用函數

  • 代碼重復過多,一個勁的copy and paste不符合高端程序員的氣質
  • 如果日后需要修改發郵件的這段代碼,比如加入群發功能,那你就需要在所有用到這段代碼的地方都修改一遍
  • 總結使用函數的好處:

    1.代碼重用

    2.保持一致性,易維護

    3.可擴展性

  • 1 while True:2 if cpu利用率 > 90%:3 #發送郵件提醒4 連接郵箱服務器5 發送郵件6 關閉連接7 8 if 硬盤使用空間 > 90%:9 #發送郵件提醒 10 連接郵箱服務器 11 發送郵件 12 關閉連接 13 14 if 內存占用 > 80%: 15 #發送郵件提醒 16 連接郵箱服務器 17 發送郵件 18 關閉連接 def 發送郵件(內容)#發送郵件提醒連接郵箱服務器發送郵件關閉連接while True:if cpu利用率 > 90%:發送郵件('CPU報警')if 硬盤使用空間 > 90%:發送郵件('硬盤報警')if 內存占用 > 80%:發送郵件('內存報警')

    3 函數和過程

    ?? 過程的定義:過程就是簡單特殊沒有返回值的函數

    ?? 這么看來我們在討論為何使用函數的的時候引入的函數,都沒有返回值,沒有返回值就是過程,沒錯,但是在python中有比較神奇的事情

    1 def test01():2 msg='hello The little green frog'3 print msg4 5 def test02():6 msg='hello WuDaLang'7 print msg8 return msg9 10 11 t1=test01() 12 13 t2=test02() 14 15 16 print 'from test01 return is [%s]' %t1 17 print 'from test02 return is [%s]' %t2

    總結:當一個函數/過程沒有使用return顯示的定義返回值時,python解釋器會隱式的返回None,

    所以在python中即便是過程也可以算作函數。

    1 def test01():2 pass3 4 def test02():5 return 06 7 def test03():8 return 0,10,'hello',['alex','lb'],{'WuDaLang':'lb'}9 10 t1=test01() 11 t2=test02() 12 t3=test03() 13 14 15 print 'from test01 return is [%s]: ' %type(t1),t1 16 print 'from test02 return is [%s]: ' %type(t2),t2 17 print 'from test03 return is [%s]: ' %type(t3),t3

    總結:

    ? ?返回值數=0:返回None

    ? ?返回值數=1:返回object

    ? ?返回值數>1:返回tuple

    ?????

    ?

    顯示返回值,函數里面可以多條return,但只能執行第一條。后面的全都終止掉了。

    ?return返回最大值

    返回最大值的倍數,這里面返回20的10倍

    ?

    轉載于:https://www.cnblogs.com/fangjie0410/p/7444243.html

    創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

    總結

    以上是生活随笔為你收集整理的字符编码和函数的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。