python基礎
語句和語法
註釋及續行
首要說明的是:儘管python可讀性最好的語言之一,這並不意味者程序員在代碼中就可以不寫註釋
和很多UNIX腳本類似,python註釋語句從#字符開始
註釋可以在一行的任何地方開始,解釋器會忽略掉該行#之後的所有內容
一行過長的語句可以使用反斜槓\分解成幾行
縮進及代碼組
縮進相同的一組語句構成一個代碼塊,稱之爲代碼組
首行以關鍵字開始,以冒號:結束,該行之後的一行或多行代碼構成代碼組
如果代碼組只有一行,可以將其直接寫在冒號後面,但是這樣的寫法可讀性差,不推薦
同行多個語句
分號;允許你將多個語句寫在同一行上
但是這些語句不能在這行開始一個新的代碼塊
因爲可讀性差,所以不推薦使用
>>> a = 3;print a
3
>>> x = 3;def foo(): print x
File "<stdin>", line 1
x = 3;def foo(): print x
^
SyntaxError: invalid syntax
變量賦值
賦值運算符
python語言中,等號=是主要的賦值運算符
賦值並不是直接將一個值賦給一個變量
在python中,對象是通過引用傳遞的。在賦值時,不管這個對象十新創建的,還是一個已經存在的,都是將該對象的引用(並不是值)賦值給變量
python也支持鏈式多重賦值
>>> x=y=1
>>> x
1
>>> y
1
增量賦值
從python 2.0開始,等號可以和一個算數運算符結合在一起,將計算結果重新賦值給左邊的變量,這被稱爲增量賦值
>>> x=1
>>> x=x+1
>>> x
2
>>> x += 1
>>> x
3
>>> x++
File "<stdin>", line 1
x++
^
SyntaxError: invalid syntax
>>> ++x
3
多元賦值
另一種將多個變量同時賦值的方法稱爲多元賦值,採用這種方式賦值時,等號兩邊的對象都是元組
>>> x,y,z=1,2,'a string'
>>> print 'x=%d,y=%d' %(x,y)
x=1,y=2
>>> x,y = y,x
>>> print 'x=%d,y=%d' %(x,y)
x=2,y=1
標識符
合法的標識符
python 標識符字符串規則和其他大部分用C編寫的高級語言相似
第一個字符必須十字母或下劃線(_)
剩下的字符可以使字母和數字或下劃線
大小寫敏感
關鍵字
和其它的高級語言一樣,python也擁有一些被稱作關鍵字的保留字符
任何語言的關鍵字應該保持相對的穩定,但是因爲python是一門不斷成長和進化的語言,其關鍵字偶爾會更新
關鍵字列表和iskyward()函數都放入了keyword模塊以便查閱
>>> import keyword
>>> keyword.iskeyword("if") #判斷if是不是關鍵字
True
>>> keyword.kwlist
['and', 'as', 'assert', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'exec', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'not', 'or', 'pass', 'print', 'raise', 'return', 'try', 'while', 'with', 'yield']
>>>
內建
除了關鍵字之外,python還有可以在任何一級代碼使用的“內建”的名字集合,這些名字可以由解釋器設置或使用
雖然built-in不是關鍵字,但是應該把它當作“系統保留字”
保留的常量如:True、False、None
>>> len = 10
>>> len('abcdf')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not callable
>>> del len
>>> len
<built-in function len>
>>> len('abcdf')
5
基本風格
模塊結構及佈局
編寫程序時,應該建立一個統一且容易閱讀的結構,並將它應用到每一個文件中去
#!/usr/bin/env python #起始行
"this is a test module" #模塊文檔字符串
import sys #導入模塊
import os
debug = True #全局變量聲明
class FooClass(object): #類定義
‘Foo class’
pass
def test(): #函數定義
"test function"
foo = FooClass()
if __name__ == '__main__': #程序主體
test()
主程序中的測試代碼
優秀的程序員和軟件工程師,總是會爲其應用程序提供一組測試代碼或者簡單教程
測試代碼僅當該文件被直接執行時運行,即被其他模塊導入時不執行
利用__name__ 變量這個有力條件,將測試代碼放在一個函數中,如果該模塊是被當成腳本運行,就調用這個函數
練習:創建文件
1、編寫一個程序,要求用戶輸入文件名
2、如果文件已經存在,要求用戶重新輸入
3、提示用戶輸入數據,每行數據先寫到列表中
4、將列表數據寫入到用戶輸入的文件中
#!/usr/bin/env python
import os
contents = []
while True:
fname = raw_input("Plz input a file name: ")
if not os.path.exists(fname):
break
print "%s already exists.Try again." % fname
while True:
data = raw_input("(Enger to quit)> ")
if not data:
break
contents.append(data + '\n')
fobj = open(fname,'w')
fobj.writelines(contents)
fobj.close()
升級版:(改成函數模式)
#!/usr/bin/env python
import os
def get_fname():
while True:
fname = raw_input("Plz input a file name: ")
if not os.path.exists(fname):
break
print "%s already exists.Try again." % fname
return fname
def get_contents():
contents = []
while True:
data = raw_input("(Enger to quit)> ")
if not data:
break
contents.append(data + '\n')
return contents
def wfile():
fobj = open(fname,'w')
fobj.writelines(contents)
fobj.close()
if __name__ == '__main__':
filename = get_fname()
lines = get_contents()
wfile(filename,lines)
python 對象
python對象基礎
python對象特性
所有的python對象都擁有三個特性:
- 身份:每一個對象都有一個唯一的身份標識自己,任何對象的身份可以使用內建函數id()來得到
>>> a = 3
>>> b = 3
>>> id(a)
146065560
>>> id(b)
146065560
- 類型:決定了該對象可以保存什麼類型的值,可以進行什麼樣的操作,以及遵循什麼樣的規則。用內建函數type()查看對象的類型
>>> a = 1
>>> type(a)
<type 'int'>
>>> a = 'hello'
>>> type(a)
<type 'str'>
>>> a = []
>>> type(a)
<type 'list'>
- 值:對象表示的數據項
python對象屬性
某些python對象有屬性、值或相關聯的可執行代碼
用.標記法來訪問屬性
最常用的屬性是函數和方法,不過有一些python類型也有數據屬性
含有數據屬性的對象包括(但不限於):類、類實例、模塊、複數和文件
python對象類型
標準類型
數字
- 整型
- 長整形
- 布爾型
- 浮點型
- 複數型
字符串
列表
元組
字典
其他內建類型
在python開發時,還可能用到的數據類型有:
- 類型
- Null對象(None)
- 文件
- 集合/固定集合
- 函數/方法
- 模塊
- 類
內部類型
以下類型通常用不到,只是爲了知識的完整性,簡要的列出:
- 代碼
- 幀
- 跟蹤記錄
- 切片
- 省略
- xrange
標準類型運算符
對象值的比較
運算符 | 功能 |
expr1 < expr2 | expr1小於expr2 |
expr1 > expr2 | expr1 大於expr2 |
expr1 <= expr2 | expr1 小於等於expr2 |
expr1 >= expr2 | expr1 大於等於expr2 |
expr1 == expr2 | expr1 等於expr2 |
expr1 != expr2 | expr1 不等於expr2 |
expr1 <> expr2 | expr1 不等於expr2 |
對象身份比較
對象可以通過引用被賦值到另一個變量
因爲每個變量都指向同一個(共享的)數據對象,只要任何一個引用發生改變,該對象的其他引用也會隨之改變
>>> aList = ['hello','bob']
>>> bList = aList
>>> id(aList)
3071001644L
>>> id(bList)
3071001644L
>>> bList[1] = 'tom'
>>> aList
['hello', 'tom']
布爾邏輯運算符
not運算符擁有最高優先級,只比所有比較運算符低一級
and 和 or 運算符則相應的在低一級
運算符 | 功能 |
not expr | expr的邏輯非(否) |
expr1 and expr2 | expr1 和expr2 的邏輯與 |
expr1 or expr2 | expr1 和expr2的邏輯或 |
數字
數字簡介
創建數值對象並賦值
數字提供了標量貯存和直接訪問
創建數值對象和給變量賦值一樣簡單
>>> anint = 1
>>> aLong = -9999999999999999999999L
>>> aFloat = 3.141325677839900349
>>> aComplex = 1.23 + 4.56J
更新數字對象
數字是不可變類型,也就是說變更數字的值會生成新的對象
在python中,變量更像一個指針指向裝變量值的盒子
對不可變類型來說,你無法改變盒子的內容,但你可以將指針指向一個新盒子
>>> i =3
>>> id(i)
146065560
>>> i = 4
>>> id(i)
146065548
刪除數字對象
按照python的法則,無法真正刪除一個數值對象,僅僅是不再使用它而已
刪除一個數值對象的引用,使用del語句
刪除對象的引用之後,就不能再使用這個引用(變量名),除非給它賦一個新值
絕大多數情況下並不需要明確del一個對象
整形
布爾型
該類型的取值只有兩個,即True和False
True的數值爲1,False的數值爲0
在判斷語句中,空列表、空元組、空字符串、空字典數值爲0的數字以及None皆爲Fasle,其他皆爲True
>>> True + 2
3
>>> if "hello": print 'Yes'
...
Yes
>>> if not []: print 'yes'
...
yes
標準整數類型
標準整數類型是最通用的數字類型
python標準整數類型等價於C的(有符號)長整型
整數一般以十進制表示
如果八進制整數以數字“0”開始,十六進制整數以“0x” 或“0X”開始,二進制整數以“0b”或“0B”開始
>>> 0x10
16
>>> 010
8
>>> 0b10
2
長整型
C或其他編譯型語言的長整數類型的取值範圍是32位或64位
python的長整數類型能表達的數值僅僅與機器支持的(虛擬)內存大小有關
在一個整數值後面加個L(大寫或小寫都可以),表示這個整數十長整型
這個整數可以是十進制,八進制,或十六進制
運算符
標準類型運算符
在做數值運算時,必須努力保證操作數是合適的數據類型
相同類型數值運算,得到的結果也是該類型的數值
不同類型數值運算,需要(顯示或隱式地)做數據類型轉換
>>> print 5/3
1
>>> print 5.0 /3
1.66666666667
混合模式運算符
算術運算符
python支持單目運算符正號(+)和負號(-)
雙目運算符,+、-、*、/、%,還有**,分別表示加法,減法,乘法,除法,取餘和冪運算
從python2.2起,還增加了一種新的整除運算符//,即地板除
>>> print 3.0/2
1.5
>>> print 3.0 // 2
1.0
>>> print round(3.0/2)
2.0
位運算符
位運算符只適用於整數
位運算符 | 功能 |
~num | 單目運算,對數的每一位取反 |
num1 << num2 | num1 左移 num2位 |
num1 >> num2 | num1 右移num2位 |
num1 & num2 | num1 與num2按位與 |
num1 ^ num2 | num1 異或 num2(相同爲0,不同爲1) |
num1 | num2 | num1 與num2 按位或 |
內建函數
標準類型函數
cmp(num1,num2)
- num1 大於num2結果爲正值
- num1 小於num2 結果爲負值
- num1 等於num2 結果爲0
str(num):將num轉換成字符串表示格式
type(obj):判斷obj類型
數字類型函數
函數int(),long(),float()和complex()來將其它數值類型轉換爲相應的數值類型
int('11') 默認十進制
int('11',base=2) 二進制
int('11',base=16)十六進制
abs():返回給定參數的絕對值;abs(10),abs(-10)
divmod():內建函數把除法和取餘運算結合起來,返回一個包含商和餘數的元組
>>> divmod(5,3)
(1, 2)
pow():進行指數運算
>>> pow(3,2)
9
>>> pow(2,3)
8
round():用於對浮點數進行四捨五入運算
>>> print 5 / 3.0
1.66666666667
>>> print round(5 / 3.0)
2.0
>>> print round(5 / 3.0,2) #保留兩位小數點。
1.67
僅用於整數的函數
hex():轉換爲字符串形式的十六進制數 eg:ex(100)
oct():轉換爲字符串形式的八進制數 eg:oct(100)
bin():轉換爲字符串形式的二進制數 eg: bin(100)
ord():接受一個字符,返回其對應的ASCII值 eg:ord('a')
chr():接受一個單字節ASCII碼整數值,返回一個字符串 eg:chr(65)
模塊psutil的使用
pip install psutil
import tab
import psutil
psutil.<tab><tab>
psutil.users()
psutil.used_phymem()
psutil.used_phymem() / 1024 / 1024
import os
os.system('free -m')
psutil.boot_time()
import time
psutil.disk_partitions()
psutil.disk_partitions()[0]
a = psutil.disk_partitions()[0]
type(a)
a.mountpoint
# pip install ecdsa
# pip install pycrypto
一個修改密碼的腳本
#!/bin/bash
if [ -z "$3"]; then
echo "Usage: $0 ipfile oldpass newpss"
exit 1
fi
ipfile=$1
oldpass=$2
newpass=$3
if [ ! -f $ipfile ]; then
ehco "$ipfile does not exists"
exit 2
fi
for ip in $(cat $ipfile)
do
expect << EOF
spawn ssh root@ip "echo $newpass | passwd --stdin root"
expect "(yes/no)?"{
send "yes\r"
expect "password:"
send "$oldpass\r"
} "password:" {send "$oldpass\r"}
expect eof
EOF
done
python程序實現(改密碼/執行遠程命令)
#!/usr/bin/env python
import sys
import paramiko
def remote_comm(host,pwd,comm):
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(host,username='root',password=pwd)
stdin,stdout,stderr = ssh.exec_command(comm)
print stdout.read()
print stdout.read()
if __name__ =='__main__':
if len(sys.argv) != 4:
print "Usage: %s ipfile oldpass newpass" %sys.argv[0]
else:
ipfile = sys.argv[1]
oldpass = sys.argv[2]
newpass = sys.argv[3]
ch_pwd = "echo %s | passwd --stdin root" % newpass
fobj = open(ipfile)
for line in fobj:
ip = line.strip() #去除字符串兩端空白
remote_comm(ip,oldpass,ch_pwd)
多線程版python(改密碼/執行遠程命令)
#!/usr/bin/env python
import sys
import paramiko
import threading
def remote_comm(host,pwd,comm):
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(host,username='root',password=pwd)
stdin,stdout,stderr = ssh.exec_command(comm)
print stdout.read(),
print stderr.read(),
if __name__ =='__main__':
if len(sys.argv) != 4:
print "Usage: %s ipfile oldpass newpass" %sys.argv[0]
else:
ipfile = sys.argv[1]
oldpass = sys.argv[2]
newpass = sys.argv[3]
ch_pwd = "echo %s | passwd --stdin root" % newpass
fobj = open(ipfile)
for line in fobj:
ip = line.strip() #去除字符串兩端空白
t = threading.Thread(target=remote_comm,args=(ip,oldpass,ch_pwd
))
t.start()