循環語句
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()