python 學習筆記day02-python循環、文件、函數、模塊

循環語句

    while 循環

        while 循環語法結構

            當需要語句不斷的重複執行時,可以使用 while 循環

                while expression:

                    while_sutie

            語句 while_suite 會被連續不斷的循環執行,直到表達式的值變成 0 或 False

        #!/usr/bin/env python
        # -- coding: utf-8 --
        sum100 = 0
        counter = 1
        while counter <=100:
            sum100 +=counter
            counter +=1
        print "result is: %d " % sum100

        break 語句

            break 語句可以結束當前循環然後跳轉到下條語句

            寫程序時,應儘量避免重複的代碼,在這種情況下可以使用 while-break 結構

         name = raw_input('username: ')
         while name != 'tom':
             name = raw_input("username: ")

            可以替換爲

        while Ture:
            name = raw_input("username: ")
            if name == 'tom'
                break
        
        #!/usr/bin/env python
        # --coding: utf-8 --

        while True:
            yn = raw_input("Continue(Y/N)? ")
            # break 作用:當 yn 在 yY 中則跳出 while 循環,即不再執行 print
            if yn in 'yY':
                break
            print 'working....'

        continue 語句

            當遇到continue語句時,程序會終止當前循環,並忽略剩餘的語句,然後回到循環的頂端

            如果仍然滿足循環條件,循環提內語句繼續執行,否則退出循環 

        #!/usr/bin/env python
        # --coding: utf-8 --

        sum100 = 0
        counter = 1
        while counter <= 100:
            counter += 1
            if counter % 2:
                continue
            sum100 += counter
        print "result is: %d " % sum100

        else 語句

            python 中的 while 語句也支持else子句

            else子句只在循環完成後執行

            break語句也會跳過else塊

        #!/usr/bin/env python
        # --coding: utf-8 --

        sum10 = 0
        i = 1
        while i <=10:
            sum10 +=1
        else:
            print sum10
插曲:

>>> import webbrowser
>>> help(webbrowser)

>>> webbrowser.open_new_tab("http://www.baidu.com")   #可以打開一個新的網頁 
True
>>> webbrowser.open_new_tab("http://192.168.2.100")   # 同上。 
True

>>> import os
>>> os.system('ls /home/qihang/')

刷博客的循環(初級模式)
#!/usr/bin/env python
# --coding: utf-8 --

import webbrowser
import time
import os
url = "http://192.168.1.107"
counter = 0

while counter < 11:
    webbrowser.open_new_tab(url)
    time.sleep(0.5) #睡0.5秒
    counter +=1
    if not counter % 10:
       os.system('killall firefox')

    for 循環

        for 循環語法結構

            python中的for接受可迭代對象(例如序列或迭代器)作爲其參數,每次迭代其中一個元素

                for iten_var in iterable:

                      suite_expression

                 >>> for ch in 'abcd':
                ...     print ch
                ...
                a
                b
                c
                d
                >>> for ch in ["hello","wold"]:
                ...     print ch
                ...
                hello
                wold

            與while循環一樣,支持break/continue/else 語句

            一般情況下,循環次數未知採用 while 循環,循環次數已知,採用 for 循環

        range 函數

            for循環常與range函數一起使用

            range函數提供循環條件

            range函數的完整語法爲:

                range(start,end,step=1)

                    >>> range(5)
                    [0, 1, 2, 3, 4]
                    >>> range(1,5)
                    [1, 2, 3, 4]
                    >>> range(1,5,2)
                    [1, 3]

                    >>> range(10,0,-1)

                    

                    >>> for i in range(3):
                    ...   print "hello world!"
                    ...
                    hello world!
                    hello world!
                    hello world!

                    >>> alist = ['bob','alict','tom','jerry']
                    >>> for i in range(len(alist)):
                    ...   print "%s: %s" %(i,alist[i])
                    ...
                    0: bob
                    1: alict
                    2: tom
                    3: jerry



        xrange 函數

            xrange()類似range(),不過當你有一個很大的範圍列表時,xrange()可以更爲適合,因爲它不會在內存裏創建列表的完整拷貝。

            它只被用在for循環中,在for循環外使用它沒有意義

            它的性能遠高出range(),因爲它不生成整個列表

                >>> for x in xrange(3):
                ...   print x
                ...
                0
                1
                2
注意:print x 後面 加“,”,可以不用換行。
斐波那契數列

    1、斐波那契數列就是某一個數,總是前兩個數之和,比如0,1,1,2,3,5,8

    2、使用for循環和range()函數編寫一個程序,加算有10個數的斐波那契數列

    3、改進程序,要求用戶輸入一個數字,可以生成用戶需要長度的斐波那契數列

        #!/usr/bin/env python
       # --coding: utf-8 --
       
num = int(raw_input("number")
       fib = [0,1]
       for i in range(num - 2):
           fib.append(fib[-1] + fib[-2])
       print fib
       一個小練習,使用python來ping 一個網段的主機存活
       #!/usr/bin/env python

       import os

       for i in range(1,255):
           ip = "192.168.1.%s" % i
           result = os.system("ping -c2 %s > /dev/null" % ip)
           if result:
               print "%s: down" %ip
           else:
               print "%s:up" %ip


        列表解析

            它是一個非常有用、簡單、而且靈活的工具,可以用來動態地創建列表

            語法:

                [expr for iter_var in iterable]

                >>> ['hello' for i in range(2)]
                     ['hello', 'hello']

                >>> [i for i in range(1,10)]
                    [1, 2, 3, 4, 5, 6, 7, 8, 9]
                    >>> [i ** 2 for i in range(1,10)]
                    [1, 4, 9, 16, 25, 36, 49, 64, 81]


            這個語句的核心是for循環,它迭代iterable對象的所有條目

            expr 應用與序列的每個成員,最後的結果是該表達式產生的列表

文件對象

    文件打開方法

        open及file 內建函數

            作爲打開文件之門的“鑰匙”,內建函數open()以及file()提供了初始化輸入/輸出(I/O)操作的通用接口

            成功打開文件後會返回一個文件對象,否則引發一個錯誤

            open()方法和file()方法可以完全相互替換

            基本語法:

                file_object = open(file_name,access_mode='r',buffering=-1)

            >>> f = open('/etc/hosts')
                >>> f
                <open file '/etc/hosts', mode 'r' at 0xb744e0d0>
                >>> f.read()
                '127.0.0.1\tlocalhost\n127.0.1.1\tqihang-Lenovo-G460\n\n# The following lines are desirable for IPv6 capable hosts\n::1     ip6-localhost ip6-loopback\nfe00::0 ip6-localnet\nff00::0 ip6-mcastprefix\nff02::1 ip6-allnodes\nff02::2 ip6-allrouters\n'

                >>> f.close()
                >>> f = open('/etc/hosts')
                >>> data = f.read()
                >>> print data,
                127.0.0.1    localhost
                127.0.1.1    qihang-Lenovo-G460

                # The following lines are desirable for IPv6 capable hosts
                ::1     ip6-localhost ip6-loopback
                fe00::0 ip6-localnet
                ff00::0 ip6-mcastprefix
                ff02::1 ip6-allnodes
                ff02::2 ip6-allrouters
                >>> f.close()



            文件對象的訪問模式:

文件模式
操作

r

以讀方式打開(文件不存在則報錯))
w
以寫方式打開(文件存在則清空,不存在則創建)
a
以追加模式打開(必要時創建新文件)
r+
以讀寫模式打開(參見r)
w+
以讀寫模式打開(參見w)
a+
以讀寫模式打開(參見a)

 文件輸入

        read方法

            read()方法用來直接讀取字節到字符串中,最多讀取給定數目個字節

            如果沒有給定size參數(默認值爲-1)或者size值爲負,文件將被讀取直至末尾

                  >>> data = fobj.read()

                        >>> print data

        readline 方法

            >>> f = open('/etc/hosts')
                >>> f.readline()
                '127.0.0.1\tlocalhost\n'
                >>> f.readline()
                '127.0.1.1\tqihang-Lenovo-G460\n'

                >>> f.close()

        readlines 方法

            >>> f = open('/etc/hosts')
               >>> f.readlines()
               ['127.0.0.1\tlocalhost\n', '127.0.1.1\tqihang-Lenovo-G460\n', '\n', '# The following lines are desirable for IPv6 capable hosts\n', '::1     ip6-localhost ip6-loopback\n', 'fe00::0 ip6-localnet\n', 'ff00::0 ip6-mcastprefix\n', 'ff02::1 ip6-allnodes\n', 'ff02::2 ip6-allrouters\n']

                >>> f.close()

        文件迭代

            如果需要逐行處理文件,可以結合 for 循環迭代文件

            迭代文件的方法與處理其他序列類型的數據類似

            >>> fobj = open("star.py")

            >>> for eachLine in fobj:

            ...    print eachLine,

            >>> f = open("/etc/hosts")
                >>> for line in f:
                ...   print line,
                ...
                127.0.0.1    localhost
                127.0.1.1    qihang-Lenovo-G460

                # The following lines are desirable for IPv6 capable hosts
                ::1     ip6-localhost ip6-loopback
                fe00::0 ip6-localnet
                ff00::0 ip6-mcastprefix
                ff02::1 ip6-allnodes
                ff02::2 ip6-allrouters
                >>> f.close()

    文件輸出

        write 方法

            write()內建方法功能與read()和readline()相反。它把含有文本數據或二進制數據塊的字符串寫入到文件中去

            寫入文件時,不會自動添加行結束標誌,需要程序員首手工輸入

            >>> fobj.write("Hello World!\n")

>>> f = open('hi.txt','w')
>>> f.read()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IOError: File not open for reading
>>> f.write(30)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: expected a character buffer object
>>> f.write('hello world!')    # f.write('hello world!\n')  加上\n 換行
>>> f.flush()
>>> exit()

>>> f  =open('hi.txt','a')
>>> f.write('new line.\n')
>>> f.close()
>>> exit()

        writelines 方法()列表方式)

                >>> f.writelines(['2rd lines\n','3rd lines\n'])

                >>> f.flush()

                >>> f.close()  


練習:模擬cp操作

    1、創建~/bin/cp.py文件

    2、將/bin/ls "拷貝"到/root目錄下

    3、要求讀取/bin/ls 後,每次讀取4096字節,依次寫入到新文件

    4、不要修改原始文件 


#!/usr/bin/env python
# coding: utf-8 --

sfname = '/bin/ls'
dfname = '/root/ls'

src_fobj = open(sfname)
dst_fobj = open(dfname,'w')

while True:
    data = src_fobj.read(4096)
    if not data:
        break
    dst_fobj.write(data)
src_fobj.close()
dst_fobj.close()

比對md5值,檢查文件是否完全相同,檢查結果爲相同。

小插曲:read文件的時候會直接佔用內存個

$ free -m
             total       used       free     shared    buffers     cached
Mem:          1941       1713        227         30         56        283
-/+ buffers/cache:       1372        568
Swap:         1972        513       1459

# dd if=/dev/zero of=ttt.img bs=1M count=100

>>> f = open('ttt.img')
>>> data = f.read()

$ free -m
             total       used       free     shared    buffers     cached
Mem:          1941       1812        128         30         56        281
-/+ buffers/cache:       1474        466
Swap:         1972        513       1459
>>> f.close()
>>> del data

$ free -m
             total       used       free     shared    buffers     cached
Mem:          1941       1722        218         30         56        281
-/+ buffers/cache:       1384        556
Swap:         1972        513       1459


函數

    函數基本操作

        函數基本概念

            函數是對程序邏輯進行結構化或過程化的一種編程方法

            將整塊代碼巧妙地隔離成易於管理的小塊

            把重複代碼放到函數中而不是進行大量的拷貝,這樣既能節省空間,也有助於保持一致性

            通常函數都是用於實現某一種功能

        創建函數

            函數是用def語句來創建的,語法如下:

                def function_name(arguments):

                    "function_documentation_string"

                    function_body_stuite

                #!/usr/bin/env python
                # --coding: utf-8 --
                #define function
                def pstar():
                    print '*' * 20
                    print "#" * 20
                # use function
                pstar()
                prstar()

            標題行由def關鍵字,函數的名字,以及參數的集合(如果有的話)組成

            def子句的剩餘部分包括了一個雖然可選但是強烈推薦的文檔字符串,和必須的函數體

        調用函數

            同大多數語言相同,python用一對圓括號調用函數

            如果沒有加圓括號,只是對函數的引用

                >>> def foo():

                ...  print "hello"

                ...

                >>> foo()

                hello

                >>> foo

                <function foo at 0x7ff2328967d0>     # 函數在內存中的地址。

        函數的返回值

            多數情況下,函數並不直接輸出數據,而是向調用者返回值

            函數的返回值使用return關鍵字

            沒有return的話,函數默認使用None   

                >>> def foo():

                ...    res = 3 + 4

                >>> i = foo()

                >>> print i

                None

    函數參數

        定義參數

            形式參數

                - 函數定義時,緊跟在函數名後(圓括號內)的參數被稱爲形式參數,簡稱形參,由於它不是實際存在變量,所以又稱虛擬變量

                #!/usr/bin/env python

                def pstar(num):

                       return '*' * num

                n = int(raw_input("number: "))

                print pstar(n)

          

             實際參數

                - 在主調函數中調用一個函數時,函數名後面括弧中的參數(可以是一個表達式)稱爲“實際參數”,簡稱實參

        傳遞參數

            調用函數時 ,實參的個數需要與形參個數一致

            實參將依次傳遞給形參

                >>> def foo(x,y):
                ...    print 'x=%d,y=%d' %(x,y)
                ...
                >>> foo()
                Traceback (most recent call last):
                  File "<stdin>", line 1, in <module>
                TypeError: foo() takes exactly 2 arguments (0 given)
                >>> foo(3)
                Traceback (most recent call last):
                  File "<stdin>", line 1, in <module>
                TypeError: foo() takes exactly 2 arguments (1 given)
                >>> foo(3,4)
                x=3,y=4
 

        位置參數

            與shell腳本類似,程序名以及參數都以位置參數的方式傳遞給python  程序

            使用sys模塊的argv列表接收

            $ vim args.py
#!/usr/bin/env python
import sys
print sys.argv

            $ python args.py hello world
            ['args.py', 'hello', 'world']

#!/usr/bin/env python
# coding: utf-8 --
import sys

def cp(sfname,dfname):

    src_fobj = open(sfname)
    dst_fobj = open(dfname,'w')

    while True:
        data = src_fobj.read(4096)
        if not data:
            break
        dst_fobj.write(data)
    src_fobj.close()
    dst_fobj.close()

cp(sys.argv[1],sys.argv[2])

          默認參數

            默認參數就是聲明瞭默認值的參數

            因爲給參數賦予了默認值,所以在函數調用時,不向該參數傳入值也是允許的

                    >>> def pstar(num = 30):
                    ...   print "*" * num
                    ...
                    >>> pstar()
                    ******************************
                    >>> pstar(40)
                    ****************************************
將cp 編程函數形式:

#!/usr/bin/env python
# coding: utf-8 --

def cp(sfname,dfname):

    src_fobj = open(sfname)
    dst_fobj = open(dfname,'w')

    while True:
        data = src_fobj.read(4096)
        if not data:
            break
        dst_fobj.write(data)
    src_fobj.close()
    dst_fobj.close()
cp('/bin/ls','/home/list')
cp('/bin/touch','/home/mytouch')


模塊

    定義模塊

        模塊基本概念

            模塊是從邏輯上組織python代碼的形式

            當代碼量變得相當大的時候,最好把代碼分成一些有組織的代碼段,前提是保證它們的彼此交互

            這些代碼片段相互間有一定的聯繫,可能是一個包含數據成員和方法的類,也可能是一組相關但彼此獨立的操作函數

        創建模塊

            模塊物理層面上組織模塊的方法十文件,每一個以.py作爲極爲的python文件都是一個模塊

            模塊名稱切記不要與系統中已存在的模塊重名

            模塊文件名字去掉後面的擴展名(.py)即爲模塊名

    使用模塊

        導入模塊(import)

            使用import導入模塊

            模塊被導入後,程序會自動生成pyc的字節碼文件以提升性能

            模塊屬性通過“模塊名.屬性”的方法調用

            如果僅需要模塊中的某些屬性,也可以單獨導入

                >>> import tab
                     >>> import sys
                     >>> import os,string

                    >>> string.digits
                    '0123456789'
                    >>> from random import randint    #導入模塊中的某個方法
                    >>> randint(1,10)
                    3

                    >>> import random as rdm   #導入random 模塊並加別名 rdm

        模塊加載(load)

            一個模塊只被加載一次,無論它被導入多少次

            只加載一次可以阻止多重導入時代碼被多次執行

            如果兩個文件相互導入,阻止了無限的相互加載

            模塊加載時,頂層代碼會自動執行,所以只將函數放入模塊的頂層是良好的編程習慣

        模塊導入的特性

            模塊具有一個__name__特殊屬性

            當模塊文件直接執行時,__name__的值爲‘__main__'

            當模塊被另一個文件導入時,__name__的值就是該模塊的名字

$ cat foo.py
#!/usr/bin/env python
print __name__

$ cat bar.py
#!/usr/bin/env python
import foo
$ python foo.py
__main__
$ python bar.py
foo


  __name__ 是python 的內部變量,在foo 中 打印 __name__ ,單獨執行時,輸出的名字是__main__,被其他程序導入後,顯示foo。

一個模塊文件自己獨立執行的時候,__name__,打印的是__main__,如果是被其他文件導入了。則__name__打印的就是模塊名


應用:

#vim star.py

#!/usr/bin/env python

def pstar(num=20):

    return '*' * num

if __name__ == '__main__':

    print pstar()

    print pstart(40)

上述代碼,單獨執行(python star.py) ,則會執行 print pstar() print pstar(),如果import star,則不會執行print pstar() print pstar()


練習:生成8位隨機密碼

1、編寫一個能生成8位隨機密碼的程序

2、使用random的choice函數隨機取出字符

3、用於密碼的字符通過string模塊獲得

4、改進程序,用戶可以自己決定生成多少位的密碼


多線程 ping

mtping.py

#!/usr/bin/env python

import os

import threading
def ping(ip):
    result = os.system("ping -c2 %s > /dev/null" % ip )
    if not result:
        print "%s:up" % ip
    else:
        print "%s:down" % ip

if __name__ == '__main__':
    for i in range(1,255):
        ipaddress = "192.168.2.%s" % i
        t = threading.Thread(target=ping,args=[ipaddr])
        t.start()


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章