python學習備忘錄–2

來源:互聯網
上載者:User

1,前言
   前面的備忘錄提到了python的基本教程,基本上本文例子都是沈潔元的簡明教程裡面的內容,這兩篇都是讀書筆記,算不上派生,主要也是自己備忘用的,譯者見諒。
   基本上本文的解釋是自己的理解,沒有採用書本中的講解,覺得自己解釋可能更容易記住。

   上篇備忘主要是面向過程來講述的,其實python是凡事都是對象的一種解釋語言。包括類型int啊等等都是對象,與C/C++顯然不同,在這兩個語言中,類型是作為原子來定義的,主要是用來分配記憶體位元組而用,沒有所謂方法,當然這點在VC中做了一定改變,比如對字串的處理顯然是比C要方便一些。

    python和perl,還是Python容易懂些,效率差了

2,物件導向的python
   2.1,類建立一個新類型,而對象這個類的 執行個體。
   2.2,對象可以使用普通的 屬於 對象的變數儲存資料。屬於一個對象或類的變數被稱為域。對象也可以使用 屬於 類的函數來具有功能。這樣的函數被稱為類的方法。域和方法可以合稱為類的屬性。
   2.3,域有兩種類型——屬於每個執行個體/類的對象或屬於類本身。它們分別被稱為執行個體變數和類變數。類使用class關鍵字建立。類的域和方法被列在一個縮排塊中。

3,類

   3.1,self參數 

             類的方法與普通的函數只有一個特別的區別——它們必須有一個額外的第一個參數名稱,但是在調用這個方法的時候你不為這個參數賦值,Python會提供這個值。這個特別的變數指對象本身,按照慣例它的名稱是self。

            self 本身不需要賦值,由python自動完成功能,如果你的執行個體調用一個方法,例如:假如你有一個類稱為MyClass和這個類的一個執行個體MyObject。當你調用這個對象的方法MyObject.method(arg1, arg2)的時候,這會由Python自動轉為MyClass.method(MyObject, arg1, arg2)
  3.2,建立一個類
    我們看下面這個例子:

      #!/usr/bin/python       # Filename: simplestclass.py       class Person:               pass # An empty block       p = Person()       print p

      如果你去掉pass前面的縮排,會提示錯誤,期待一個縮排,一定要記住python是由縮排來區別語句塊的,習慣C的人要留心。
      結果列印的是這個執行個體的記憶體位址。

       再者要注意的是:python中表示空語句必須寫個pass,而不是像C中括弧一括完事,因為python是用縮排來區別語句塊的。所以你不縮排,解譯器就不懂了。
  3.3,對象的方法
      對象方法與函數類似,只不過多了一個額外的self變數。
      我們來看一個方法:

      #!/usr/bin/python      # Filename: method.py     class Person:             def sayHi(self):                print 'Hello, how are you?'    p = Person()    p.sayHi()

    # This short example can also be written as Person().sayHi()
   要注意sayHi方法沒有任何參數。我個人覺得之所以需要一個self做方法預設參數可能是由於python是門解釋型語言,便於解譯器解釋。剛學這隻是種感覺,不對之處請指正。

   3.4,一些特殊方法
        這裡面其實涉及了一些並不陌生的概念
   3.4.1 __init__方法
        這個方法其實就是建構函式啊,大家懂了吧,而且上篇沒有提到,python是變數不需要事前聲明的,說實話看到下面這個例子,還是多少有點不適應

 #!/usr/bin/python            # Filename: class_init.py            class Person:                def __init__(self, name):                       self.name = name           def sayHi(self):           print 'Hello, my name is', self.name           p = Person('Swaroop')           p.sayHi()           # This short example can also be written as Person('Swaroop').sayHi()

這裡面的屬性域沒有聲明啊,也不說什麼類型,在文法嚴格C++中顯的是相當糟糕。

建立一個類的新執行個體的時候,把參數包括在圓括弧內跟在類名後面,從而傳遞給__init__方法。

這個你要是習慣C++/Java之類的強制類型申明語言,看到這個self.name很不適應。還是把self參數當成系統需要的參數就好了。

下面這個例子可以解釋一下為什麼執行個體的屬性域可以不用聲明,對於python而已,建立執行個體適合,調用的__init__方法

#!/usr/bin/python# Filename: objvar.pyclass Person:    '''Represents a person.'''    population = 0    def __init__(self, name):        '''Initializes the person's data.'''        self.name = name        print '(Initializing %s)' % self.name        # When this person is created, he/she        # adds to the population        Person.population += 1    def __del__(self):        '''I am dying.'''        print '%s says bye.' % self.name        Person.population -= 1        if Person.population == 0:            print 'I am the last one.'        else:            print 'There are still %d people left.' % Person.population    def sayHi(self):        '''Greeting by the person.        Really, that's all it does.'''        print 'Hi, my name is %s.' % self.name    def howMany(self):        '''Prints the current population.'''        if Person.population == 1:            print 'I am the only person here.'        else:            print 'We have %d persons here.' % Person.populationswaroop = Person('Swaroop')swaroop.sayHi()swaroop.howMany()kalam = Person('Abdul Kalam')kalam.sayHi()kalam.howMany()swaroop.sayHi()swaroop.howMany()

     觀察可以發現__init__方法用一個名字來初始化Person執行個體。在這個方法中,我們讓population增加1,這是因為我們增加了一個人。同樣可以發現,self.name的值根據每個對象指定,這表明了它作為對象的變數的本質。

    運行上述指令碼,提示Exception AttributeError: "'NoneType' object has no attribute 'population'" in <bound method Person.__del__ of <__main__.Person instance at 0xb7746eec>> ignored;

    原因是對象銷毀時,全域變數的問題。

    我另寫了一篇備忘,記錄學習一下錯誤和心得,這裡先列出遇到的問題。記住一點,不要使用__def__方法。

     你只能使用self變數來參考同一個對象的變數和方法。這被稱為 屬性參考 。
     在這個程式中,我們還看到docstring對於類和方法同樣有用。我們可以在運行時使用Person.__doc__和Person.sayHi.__doc__來分別訪問類與方法的文檔字串。
      就如同__init__方法一樣,還有一個特殊的方法__del__,它在對象消逝的時候被調用。對象消逝即對象不再被使用,它所佔用的記憶體將返回給系統作它用。在這個方法裡面,我們只是簡單地把Person.population減1。

       當對象不再被使用時,__del__方法運行,但是很難保證這個方法究竟在 什麼時候 運行。

我們正常運行一次:

我們在這個指令碼裡面添加:
print Person.__doc__
print Person.sayHi.__doc__
我們看下運行結果:
b2c@b2c-server:~$ python demo.py 
(Initializing Swaroop)
Hi, my name is Swaroop.
I am the only person here.
(Initializing Abdul Kalam)
Hi, my name is Abdul Kalam.
We have 2 persons here.
Hi, my name is Swaroop.
We have 2 persons here.
Represents a person.
Greeting by the person.

        Really, that's all it does.
Abdul Kalam says bye.
There are still 1 people left.
Swaroop says bye.
I am the last one.

有沒有發現什嗎?可以看到我們的文檔字串或者說是解說文字不是最後顯示,而指令碼中其實是最後兩條語句,這個是因為__del__方法,指令碼執行最後,執行個體被銷毀,所以方法執行,出現提示。明白了沒。
所以這個__del__是解構函式,類似概念。

這裡面多說一句,python其實類中成員預設都是公開的,私人成員是後來語言加入的特性,以雙底線__作為標誌。如一個變數__var為私人變數,包括子類在內的外部調用都是無效的。python 是採用從新命名這個私人變數名字而避開外部調用的,非常簡單,所以會提示你找不到。

縮排要注意邏輯對齊!

  3.5,繼承

     物件導向的核心概念之一,為了代碼重用和邏輯相關性而定義。有過OOP基礎的都應該不陌生。
子類型執行個體可以自然的被當作父類型使用,支援多重繼承。

     #!/usr/bin/python# Filename: inherit.pyclass SchoolMember:    '''Represents any school member.'''    def __init__(self, name, age):        self.name = name        self.age = age        print '(Initialized SchoolMember: %s)' % self.name    def tell(self):        '''Tell my details.'''        print 'Name:"%s" Age:"%s"' % (self.name, self.age),class Teacher(SchoolMember):    '''Represents a teacher.'''    def __init__(self, name, age, salary):        SchoolMember.__init__(self, name, age)        self.salary = salary        print '(Initialized Teacher: %s)' % self.name    def tell(self):        SchoolMember.tell(self)        print 'Salary: "%d"' % self.salaryclass Student(SchoolMember):    '''Represents a student.'''    def __init__(self, name, age, marks):        SchoolMember.__init__(self, name, age)        self.marks = marks        print '(Initialized Student: %s)' % self.name    def tell(self):        SchoolMember.tell(self)       print 'Marks: "%d"' % self.markst = Teacher('Mrs. Shrividya', 40, 30000)s = Student('Swaroop', 22, 75)print # prints a blank linemembers = [t, s]for member in members:    member.tell() # works for both Teachers and Students

這個例子可以看出繼承的基本含義。另外說一點,子類建構函式必須人工構造父類的建構函式,不能自動完成,這點與其他OOP語言有點區別。
    Python不會自動調用基本類的constructor,你得親自專門調用它。

4,I/O

   4.1,檔案

你可以通過建立一個file類的對象來開啟一個檔案。

這個IO操作還是比較方便,能直接調用file()

#!/usr/bin/python# Filename: using_file.pypoem = '''\Programming is funWhen the work is doneif you wanna make your work also fun:        use Perl!'''f = file('poem.txt', 'w') # open for 'w'ritingf.write(poem) # write text to filef.close() # close the filef = file('poem.txt')# if no mode is specified, 'r'ead mode is assumed by defaultwhile True:   line = f.readline()   if len(line) == 0: # Zero length indicates EOF       break   print line,   # Notice comma to avoid automatic newline added by Pythonf.close() # close the file 

我們通過指明我們希望開啟的檔案和模式來建立一個file類的執行個體。模式可以為讀模式('r')、寫入模式('w')或追加模式('a')。事實上還有多得多的模式可以使用,你可以使用help(file)來瞭解它們的詳情。
如果沒有指定模式,讀將作為預設模式。

在一個迴圈中,我們使用readline方法讀檔案的每一行。這個方法返回包括行末分行符號的一個完整行。所以,當一個 空的 字串被返回的時候,即表示檔案末已經到達了,於是我們停止迴圈。

這裡面有個小疑問就是while語句的true是根據上下文來判斷的嗎?我改成f也是可以的.

注意,因為從檔案讀到的內容已經以分行符號結尾,所以我們在print語句上使用逗號來消除自動換行。最後,我們用close關閉這個檔案。

  

4.2 儲存空間

Python提供一個標準的模組,稱為pickle。使用它你可以在一個檔案中儲存任何Python對象,之後你又可以把它完整無缺地取出來。這被稱為 持久地 儲存對象。
還有另一個模組稱為cPickle,它的功能和pickle模組完全相同,只不過它是用C語言編寫的,因此要快得多(比pickle快1000倍)。C就是牛逼啊。哈哈

#!/usr/bin/python# Filename: pickling.pyimport cPickle as p#import pickle as pshoplistfile = 'shoplist.data'# the name of the file where we will store the objectshoplist = ['apple', 'mango', 'carrot']# Write to the filef = file(shoplistfile, 'w')p.dump(shoplist, f) # dump the object to a filef.close()del shoplist # remove the shoplist# Read back from the storagef = file(shoplistfile)storedlist = p.load(f)print storedlist

首先,請注意我們使用了import..as文法。這是一種便利方法,以便於我們可以使用更短的模組名稱。在這個例子中,它還讓我們能夠通過簡單地改變一行就切換到另一個模組(cPickle或者pickle)!在程式的其餘部分的時候,我們簡單地把這個模組稱為p。

為了在檔案裡儲存一個對象,首先以寫入模式開啟一個file對象,然後調用儲存器模組的dump函數,把對象儲存到開啟的檔案中。這個過程稱為 儲存 。

接下來,我們使用pickle模組的load函數的返回來取回對象。這個過程稱為 取儲存 。
這個是涉及I/O操作用的

5,異常處理
    應該說進階語言裡面都有異常處理的內容。
    我們程式出現問題的適合,解譯器會告訴我們出錯了,有些時候對使用者顯示這些顯然是不友好的。所以,有點類似catch...throw,這裡面有try...except。

#!/usr/bin/python# Filename: try_except.pyimport systry:    s = raw_input('Enter something --> ')except EOFError:    print '\nWhy did you do an EOF on me?'    sys.exit() # exit the programexcept:    print '\nSome error/exception occurred.'    # here, we are not exiting the programprint 'Done'

這個程式運行以後,按“Ctrl+C”或者“Ctrl+D”看看結果。。

5.2,自訂異常
    可以自己定義異常來顯示。
     你可以使用raise語句 引發 異常。你還得指明錯誤/異常的名稱和伴隨異常 觸發的 異常對象。你可以引發的錯誤或異常應該分別是一個Error或Exception類的直接或間接匯出類。
    自己定義的異常類要是Exception類的子類。

    這裡,我們建立了我們自己的異常類型,其實我們可以使用任何預定義的異常/錯誤。這個新的異常類型是ShortInputException類。它有兩個域——length是給定輸入的長度,atleast則是程式期望的最小長度。

在except從句中,我們提供了錯誤類和用來表示錯誤/異常對象的變數。這與函數調用中的形參和實參概念類似。在這個特別的except從句中,我們使用異常對象的length和atleast

#!/usr/bin/python# Filename: raising.pyclass ShortInputException(Exception):    '''A user-defined exception class.'''    def __init__(self, length, atleast):        Exception.__init__(self)        self.length = length        self.atleast = atleasttry:    s = raw_input('Enter something --> ')    if len(s) < 3:        raise ShortInputException(len(s), 3)    # Other work can continue as usual hereexcept EOFError:    print '\nWhy did you do an EOF on me?'except ShortInputException, x:    print 'ShortInputException: The input was of length %d, \          was expecting at least %d' % (x.length, x.atleast)else:    print 'No exception was raised.'

    這裡,我們建立了我們自己的異常類型,其實我們可以使用任何預定義的異常/錯誤。這個新的異常類型是ShortInputException類。它有兩個域——length是給定輸入的長度,atleast則是程式期望的最小長度。

   在except從句中,我們提供了錯誤類和用來表示錯誤/異常對象的變數。這與函數調用中的形參和實參概念類似。在這個特別的except從句中,我們使用異常對象的length和atleast域來為使用者列印一個恰當的訊息.

5.3,try..finally
     單詞意思可知,finally是無論異常發生與否都要完成的動作。

 #!/usr/bin/python# Filename: finally.pyimport timetry:    f = file('poem.txt')    while True: # our usual file-reading idiom        line = f.readline()        if len(line) == 0:            break        time.sleep(2)        print line,finally:    f.close()    print 'Cleaning up...closed the file'

睡了2秒,是故意延長時間,好讓你按“Ctrl+C”,按了你也發現,檔案還是關閉了最後。

6,python標準庫
 6.1,sys模組
     顧名思義,系統庫。

 #!/usr/bin/python# Filename: cat.pyimport sysdef readfile(filename):    '''Print a file to the standard output.'''    f = file(filename)    while True:        line = f.readline()        if len(line) == 0:            break        print line, # notice comma    f.close()# Script starts from hereif len(sys.argv) < 2:    print 'No action specified.'    sys.exit()if sys.argv[1].startswith('--'):    option = sys.argv[1][2:]    # fetch sys.argv[1] but without the first two characters    if option == 'version':        print 'Version 1.2'    elif option == 'help':        print '''\This program prints files to the standard output.Any number of files can be specified.Options include:  --version : Prints the version number  --help    : Display this help'''    else:        print 'Unknown option.'    sys.exit()else:    for filename in sys.argv[1:]:        readfile(filename)

這裡面說明一下:argv自動將指令檔名認為是argv[0],從0開始計數,與C語言一樣,如果出現argv[1][2:]則是第二個參數,使用者角度是第一個參數拋棄前兩個字元,截取剩餘字元的意思。
至於argv[1:]則應該是從使用者角度的第一個參數依次到參數列表的最後。
readfile()函數輸出檔案內容,首先判斷參數數量,少於2個顯然是沒有輸入檔案名稱,給出提示反饋,如果參數是以--開頭的則拋棄前兩個字元,截取剩下字元通過流程匹配分別輸出提示。最後,把參數列表中的檔案一個個輸出就是了

這裡面有三個模組比較常用先記下:sys.stdin、sys.stdout和sys.stderr它們分別對應你的程式的標準輸入、標準輸出和標準錯誤流。

   6.2,OS模組
這個模組包含普遍的作業系統功能。如果你希望你的程式能夠與平台無關的話,這個模組是尤為重要的。即它允許一個程式在編寫後不需要任何改動,也不會發生任何問題,就可以在Linux和Windows下運行。一個例子就是使用os.sep可以取代作業系統特定的路徑分割符。
        這個對於我那是相當重要了,畢竟現在用LINUX案頭的人簡直是鳳毛麟角啊。
        os模組裡面有很多方法很有用,平時可以查看一下文檔。

os.name字串指示你正在使用的平台.os.getcwd()函數得到當前工作目錄。os.linesep字串給出當前平台使用的行終止符。os.path.isfile()和os.path.isdir()函數分別檢驗給出的路徑是一個檔案還是目錄。類似地,os.path.existe()函數用來檢驗給出的路徑是否真地存在。

基本上python基本東西都在這裡麼了,當然講的也是皮毛,在以後真正開發中我會不斷新增內容和學習備忘的。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.