日本好好热aⅴ|国产99视频精品免费观看|日本成人aV在线|久热香蕉国产在线

  • <cite id="ikgdy"><table id="ikgdy"></table></cite>
    1. 西西軟件園多重安全檢測下載網(wǎng)站、值得信賴的軟件下載站!
      軟件
      軟件
      文章
      搜索

      首頁編程開發(fā)其它知識 → 如何編寫Python腳本替換文件中的多行字符?

      如何編寫Python腳本替換文件中的多行字符?

      相關軟件相關文章發(fā)表評論 來源:本站整理時間:2010/12/9 8:50:42字體大。A-A+

      作者:佚名點擊:873次評論:0次標簽: Python 字符替換

      《派森》(Python)3.13 win32 英文安裝版
      • 類型:編程工具大小:21M語言:英文 評分:8.7
      • 標簽:
      立即下載

       在大概3個月之前,Python對我來說一直是個迷。然而,就在3個月前我經(jīng)理給我一個任務——刪除(替換)所有項目源碼文件中包含特定幾行內(nèi)容的所有注釋。整個項目源碼的大小有1G,在Linux服務器(中高檔)上編譯需要半個多小時,可見代碼量之大,不可能手動去一個一個改。肯定得用腳本去處理,于是我想到了Python。在這之前沒有接觸過Python,花了2個星期一頓惡補之后,總算順利交差了。

      一直很想和大家分享一下碰到的問題及我如何解決的(可能我的方案并不好,但是他能夠解決我的問題),但一直拖到現(xiàn)在是因為我感覺我還對Python的了解還不夠。因為要在短時間內(nèi)完成上面交下來的任務,在學習Python的時候,都是走馬觀花,對解決自己的問題不相關的直接跳過,看資料也靜不下心,腦海里都是問題。前幾天我靜下心把Python的書從頭到尾瀏覽了一遍,感覺現(xiàn)在是時候要進行總結(jié)了。

      本文的主要內(nèi)容如下:

      問題描述
      解題思路
      代碼實現(xiàn)
      Python的特點
      1、問題描述
      項目源碼很大,屬于C/C++混合的那種,編程風格也很多樣,有'.c'、'.cc'、'cpp'、'.h'、'.hh'等文件。我要完成的任務是:把包含特定幾行內(nèi)容的注釋刪掉,如(聲明:下面的內(nèi)容只是我隨便舉的一個例子,項目源碼中不涉及下面的內(nèi)容。)

      /*
      * Copyright 2002 Sun Microsystems, Inc. All rights reserved.

      *

      * Redistribution and use in source and binary forms, with or without

      * modification, are permitted provided that the following conditions

      * are met:

      *

      * - Redistributions of source code must retain the above copyright

      * notice, this list of conditions and the following disclaimer.

      *

      * - Redistribution in binary form must reproduce the above copyright

      * notice, this list of conditions and the following disclaimer in

      * the documentation and/or other materials provided with the

      * distribution.

      *

      * Neither the name of Sun Microsystems, Inc. or the names of

      * contributors may be used to endorse or promote products derived

      * from this software without specific prior written permission.

      */

      但是格式有很多種,如有的在“ Copyright 2002 Sun Microsystems, Inc. All rights reserved.”前面有一段關于本源碼文件的描述、有的在“from this software without specific prior written permission.”后面有一段關于本源碼文件的描述、有的是C++風格的注釋用"http://",而不是“/**/”、還有的沒有

      “ * - Redistribution in binary form must reproduce the above copyright

      * notice, this list of conditions and the following disclaimer in

      * the documentation and/or other materials provided with the

      * distribution.”等等還有其他一些?傊痪湓,我要刪除的包含特定幾行內(nèi)容的注釋有很多中格式!

      于是我決定要用Python來編寫腳本處理。要匹配特定的內(nèi)容,我想到了用正則表達式,但苦于不知道如何去構(gòu)建正則來匹配上面描述的內(nèi)容(您知道的話,希望能夠告訴我)!我只有另辟路徑了。

      2、解題思路
      我的思路——要刪除所有項目源碼中包含特定幾行內(nèi)容的注釋,腳本要滿足以下幾點功能:

      腳本要能夠遍歷所有的源碼文件('.c'、'.cc'、'cpp'、'.h'、'.hh'),并只處理上面的幾種類型的文件
      找出包含特定幾行內(nèi)容的注釋,并刪除之
      能夠處理一些特殊情況,如軟連接文件
      上面的幾點的處理步驟可以表示如下:

      Step 1:輸入要處理源碼文件夾名,或者源碼文件名;

      Step 2:如果是文件名,檢查文件的類型是否為'.c'、'.cc'、'cpp'、'.h'、'.hh',否則不處理;

      Step 3:檢查文件是否是軟連接,如果是軟連接則不處理;

      Step 4:查找文件中是否存在匹配的注釋,存在則刪掉,否則不處理;

      Step 5:如果是文件夾,則對文件夾中的每個文件、文件夾進行處理,轉(zhuǎn)Step2.

      思路很明確,關鍵是如何查找文件中是否包含匹配的內(nèi)容,并刪除!還有就是,對于一個沒用過Python等腳本語言的人來說,如何編碼實現(xiàn)也是一個問題!

      如何確定注釋是否為包含特定幾行內(nèi)容的注釋?我的思路如下:(因為正則表達式學的不好,只有通過下面的方法了)

      如果是/*、//則記錄下當前的文件行數(shù),即行號startLine
      以行為單位查找是否存在特定的幾行,如“ Copyright 2002 Sun Microsystems, Inc. All rights reserved.”等等
      直到遇到*/,或注釋結(jié)束了(對于//)。如果存在,則記錄下注釋結(jié)束的行號endLine
      最后,刪掉這從startLine ~ endLine的內(nèi)容。
      3、代碼實現(xiàn)
      廢話我不多說了,直接按照上面的實例實現(xiàn)代碼,如果你對Python不熟,請參閱相關資料。
      #!/usr/bin/env python
      #
      Filename: comment.py

      import os, sys, fileinput

      #-------------------------------------------------------------
      def usage():
         
      print u'''
          help: comment.py <filename | dirname>

          [dirname]: Option, select a directory to operate
          [filename]: Option, select a file to operate

          Example: python comment.py /home/saylor/test
         
      '''
      #--------------------------------------------------------------
      def commentFile(src, fileList):
         
      '''
          description: comment files
          param src: Operate file name
         
      '''
         
      #if file exist?
          ifnot os.path.exists(src):
             
      print'Error: file - %s doesn\'t exist.'% src
              return False
         
      if os.path.islink(src):
             
      print'Error: file - %s is just a link, will not handle it.'
             
      return False
          filetype
      = (os.path.splitext(src))[1]
         
      ifnot filetype in ['.c','.h']:
             
      return False
         
      try:
             
      ifnot os.access(src, os.W_OK):
                  os.chmod(src,
      0664)
         
      except:
             
      print'Error: you can not chang %s\'s mode.'% src
          try:
              inputf
      = open(src, 'r')
              outputfilename
      = src +'.tmp'
              outputf
      = open(outputfilename, 'w')
          beginLine
      = 0
          endLine
      =100000000
          isMatched
      = False

         
      #-----find the beginLine and endLine -------------------
              for eachline in fileinput.input(src):
             
      if eachline.find('/*') >= 0:
              beginLine
      = fileinput.lineno()
             
      if eachline.find('Copyright 2002 Sun Microsystems, Inc. All rights reserved.') >= 0:
                  isMatched
      = True
             
      if eachline.find('*/') >= 0 and isMatched:
              endLine
      = fileinput.lineno()
             
      break
         
         
      #-----delete the content between beginLine and endLine-----
          print beginLine, endLine
          lineNo
      =1
         
      for eachline in inputf:
             
      if lineNo < beginLine:
             
      print eachline
              outputf.write(eachline)
             
      elif lineNo > endLine:
             
      print eachline
              outputf.write(eachline)
              lineNo
      = lineNo +1
             
              inputf.close()
              outputf.close()
              os.rename(outputfilename, src)
              fileList.append(src)
         
      except:
             
      print'Error: unexcept error.'
              inputf.close()
              outputf.close()
         
      return True

      #--------------------------------------------------------------
      def commentDir(src, fileList):
         
      '''
          description:
               comment files in src(dir)
          param src:
               operate files in src(dir)
         
      '''
         
      #if dir exist?
          ifnot os.path.exists(src):
             
      print'Error: dir - %s is not exist.'%s (src)
             
      return False
          filelists
      = os.listdir(src)
         
      for eachfile in filelists:
              eachfile
      = src +'/'+eachfile
             
      if os.path.isdir(eachfile):
                  commentDir(eachfile, fileList)
             
      elif os.path.isfile(eachfile):
                  commentFile(eachfile, fileList)
         
      return True

      #--------------------------------------------------------------
      def main():
         
      if len(sys.argv) <2:
              usage()
              sys.exit(
      1)
          src
      = sys.argv[1]
         
      if os.path.isdir(src):
              dire
      = os.path.abspath(src)
              dirFlag
      = True
         
      elif os.path.isfile(src):
              fl
      = os.path.abspath(src)
              dirFlag
      = False
         
      else:
             
      print'Error'
          fileList
      = []
         
      if dirFlag:
              commentDir(dire, fileList)
         
      else:
              commentFile(fl, fileList)
         
      if fileList:
             
      print'Successful handle file: ...'
             
      for eachfile in fileList:
                 
      print eachfile
         
      print'Done'
         
      return True

      #--------------------------------------------------------------
      if__name__=='__main__':
          main()

      4、Python的特點
      Python入門我強烈推薦下面的資料,深入學習請閱讀其它資料:

      《A Byte of Python》http://www.swaroopch.com/notes/Python

      《簡明 Python 教程》http://woodpecker.org.cn/abyteofpython_cn/chinese/

      Python的設計哲學是“優(yōu)雅”、“明確”、“簡單”。因此,Perl語言中“總有多種方法來做同一件事”的理念在Python開發(fā)者中通常是難以忍受的。Python開發(fā)者的哲學是“用一種方法,最好是只有一種方法來做一件事”。在設計Python語言時,如果面臨多種選擇,Python開發(fā)者總會拒絕花哨的語法,而選擇明確的沒有或者很少有歧義的語法。由于這種設計觀念的差異,Python源代碼通常認為比Perl具備更好的可讀性。

      Python開發(fā)人員盡量避開不成熟或者不重要的優(yōu)化。一些針對非重要部位的加快運行速度的補丁通常不會被合并到Python內(nèi)。所以很多認為Python很慢。不過,根據(jù)二八定律,大多數(shù)程序?qū)λ俣纫蟛桓摺T谀承⿲\行速度要求很高的情況,Python程序員傾向于使用JIT技術(shù),或者用使用C/C++語言改寫這部分程序。目前可用的JIT技術(shù)是Pysco。Cython可以將Python代碼轉(zhuǎn)換成C代碼。

      相對于Lisp這種傳統(tǒng)的函數(shù)式編程語言,Python對函數(shù)式編程只提供了有限的支持。有兩個標準庫(functools, itertools)提供了Haskell和Standard ML中久經(jīng)考驗的函數(shù)式編程工具。

      雖然Python可能被粗略地分類為「腳本語言」(script language),但實際上一些大規(guī)模軟件開發(fā)計劃例如Zope、Mnet及BitTorrent,Google也廣泛地使用它。Python的支持者較喜歡稱它為一種高階動態(tài)編程語言,原因是「腳本語言」泛指僅作簡單編程任務的語言,如shell script、JavaScript等只能處理簡單任務的編程語言,並不能與Python相提并論。

      Python本身被設計為可擴展的。并非所有的特性和功能都集成到語言核心?梢允褂肅語言、C++、Cython來編寫擴展模塊。Python解釋器本身也可以被集成到其它需要腳本語言的程序內(nèi)。因此,很多人還把Python作為一種「膠水語言」(glue language)使用。使用Python將其他語言編寫的程序進行集成和封裝。在Google內(nèi)部的很多項目使用C++編寫性能要求極高的部分,然后用Python調(diào)用相應的模塊。

      Python的特點:
      1、第一行是特殊形式的注釋:它被稱作 組織行 ——源文件的頭兩個字符是#!,后面跟著一個程序。這行告訴你的Linux/Unix系統(tǒng)當你 執(zhí)行 你的程序的時候,它應該運行哪個解釋器。建議使用這種形式——#!/usr/bin/env python,而不是——#!/usr/bin/python。
      2、縮進很重要。Python使用縮進而不是一對花括號來劃分語句塊。
      3、關鍵參數(shù)的概念很有用
      4、None 返回"沒有任何東西",每一個函數(shù)默認返回None
      5、pass 空語句塊
      6、文檔字符串,__doc__,沒多大用。但是一個好的Python程序,應該要有文檔字符串,且一般遵循:“文檔字符串的慣例是一個多行字符串,它的首行以大寫字母開始,句號結(jié)尾。第二行是空行,從第三行開始是詳細的描述。 ”
      6、python中引入模塊后(import)首先就要執(zhí)行模塊的主塊,當然模塊中可能全是函數(shù)。如果要避免使用模塊名稱:from 模塊名 import 符號名,那麼使用該符號名就不用使用模塊名+點號+符號名,但是不推薦,容易造成程序不容易讀,而且容易出錯(特別是在python簡潔而簡單的語法的基礎上) import... as ... 起一個別名
      7、模塊的__name__屬性,相當有用,解決了import的缺點,可以實現(xiàn)如果不是運行的本模塊而被調(diào)用,不調(diào)用主塊
      #!/usr/bin/env python# Filename: using_name.pyif __name__ == '__main__':print 'This program is being run by itself'else:print 'I am being imported from another module'
      8、刪除一個變量/名稱,你將無法再使用該變量——它就好像從來沒有存在過一樣。
      9、可以使用內(nèi)建的dir函數(shù)來列出模塊定義的標識符。標識符有函數(shù)、類和變量。當你為dir()提供一個模塊名的時候,它返回模塊定義的名稱列表。如果不提供參數(shù),它返回當前模塊中定義的名稱列表
      10、元組語法與list相似,意義相當于枚舉,可以為空,如果只含有一個元素,需要加逗號以區(qū)別于表達式(“one”, )
      11、元組最通常的用法是用在打印語句中,可以使用格式控制符
      #!/usr/bin/env python# Filename: print_tuple.pyage = 22name = 'Swaroop'print '%s is %d years old' % (name, age)print 'Why is %s playing with that python?' % name
      12、有一個內(nèi)建的字典類型,但是沒有沖突的解決方案,但這確實是字典的定義,想要更好的結(jié)構(gòu)就自己實現(xiàn)吧。語法:{key:value, key1:value1,...}
      13、序列的概念:列表、元組和字符串都是序列,支持索引操作符和切片操作符。索引操作符讓我們可以從序列中抓取一個特定項目。切片操作符讓我們能夠獲取序列的一個切片,即一部分序列。索引可以是負數(shù),在那樣的情況下,位置是從序列尾開始計算的。序列的神奇之處在于你可以用相同的方法訪問元組、列表和字符串。
      14、如果你想要復制一個列表或者類似的序列或者其他復雜的對象(不是如整數(shù)那樣的簡單 對象 ),那么你必須使用切片操作符來取得拷貝。如果你只是想要使用另一個變量名,兩個名稱都 參考 同一個對象,那么如果你不小心的話,可能會引來各種麻煩。[淺拷貝和深拷貝的關系]
      15、str類有很多方法,如果要非常熟悉str的操作,參考help(str)
      16、剩下的就是掌握很多系統(tǒng)庫了,這個要靠經(jīng)驗,比如說os.system(命令)可用于執(zhí)行shell命令,了解的庫越多,python就會讓你完成更強大的功能。
      17、接下來是面向?qū)ο,基本概念一樣,this由代替self, 而且這個名字不一定要寫成self,任何名字都可以,這也帶來了一個缺點,你必須在形參里面指定,調(diào)用函數(shù)時不用傳遞該參數(shù)。
      構(gòu)造函數(shù):__init__(self, ......)
      析構(gòu)函數(shù):__del__ 對象滅亡時或者調(diào)用del時被調(diào)用
      Python中所有的類成員(包括數(shù)據(jù)成員)都是公共的 ,所有的方法都是有效的 。只有一個例外:如果你使用的數(shù)據(jù)成員名稱以 雙下劃線前綴 比如__privatevar,Python的名稱管理體系會有效地把它作為私有變量。
      支持多重繼承
      18、如果你已經(jīng)厭煩了java、c++的讀寫文件,那么python會讓你重新喜歡上文件讀寫,python主張解決問題的方案越少越好,寫文件就一個f = file(name, 'w'),f.write(...)讀文件也一樣,f = file(name),f.read或readline,最后close
      19、cPickle和pickle是叫做存儲器的重要模塊,可以非常方便地將一個對象存儲到一個文件,然后再取存儲從文件中取出來pickle.dump(object, file object),構(gòu)造對象時,pickle.load(file object) [儲存、取存儲]
      20、異常:raise,except,try...finally
      21、sys模塊和os模塊有很多強大功能。
      22、在函數(shù)中接收元組和列表當要使函數(shù)接收元組或字典形式的參數(shù)的時候,有一種特殊的方法,它分別使用*和**前綴。這種方法在函數(shù)需要獲取可變數(shù)量的參數(shù)的時候特別有用。
      23、lambda形式:lambda語句被用來創(chuàng)建新的函數(shù)對象,并且在運行時返回它們。lambda語句用>來創(chuàng)建函數(shù)對象。本質(zhì)上,lambda需要一個參數(shù),后面僅跟單個表達式作為函數(shù)體,而表達式的值被這個新建的函數(shù)返回。注意,即便是print語句也不能用在lambda形式中,只能使用表達式。
      24、exec、eval、assert、repr函數(shù)和反引號用來獲取對象的可打印的表示形式。你可以通過定義類的__repr__方法來控制你的對象在被repr函數(shù)調(diào)用的時候返回的內(nèi)容。
      最后,感謝實習所在公司給我足夠的時間和機會去學習新的東西。還有要感謝學習Python期間,編寫參閱資料的人。期間我參閱了下面的資料(包括上面推薦的資料):

      wiki:http://zh.wikipedia.org/zh/Python
      Chinaunix的Python論壇資料
      《OReilly-Learning-Python-4th-Edition-Oct-2009》
      當然還有前面提到過的入門資料:簡明 Python 教程(中),對應的英文版是A Byte of Python

        相關評論

        閱讀本文后您有什么感想? 已有人給出評價!

        • 8 喜歡喜歡
        • 3 頂
        • 1 難過難過
        • 5 囧
        • 3 圍觀圍觀
        • 2 無聊無聊

        熱門評論

        最新評論

        發(fā)表評論 查看所有評論(0)

        昵稱:
        表情: 高興 可 汗 我不要 害羞 好 下下下 送花 屎 親親
        字數(shù): 0/500 (您的評論需要經(jīng)過審核才能顯示)