web2py官方文檔翻譯02

python語言
最美代碼
web2py官方文檔翻譯
2016年2月10日
python

關於Python
Python是一種通用的高級編程語言。它的設計思想是強調程序員的工做效率及代碼的可讀性。它有一個最低限度的核心語法,包括不多的基本命令以及簡單語義,但與此同時它又有一個大規模的全面的標準庫,包括許多面向底層操做系統(OS)函數的應用編程接口(API)。Python代碼,在簡約的同時,定義了內置對象,例如列表 (list)、元組(tuple)、哈希表(字典dict)以及任意長度整型數(long)。
Python支持多重編程架構,包括面向對象(class)、指令 (def)、以及函數 (lambda)編程,Python還有一套動態類型系統以及經過引用計數實現的(相似於Perl、Ruby和Scheme)自動內存管理。
Python最初由Guido van Rossum於1991年發佈。該語言是開源的、基於社區開發模型的,由非盈利的Python軟件基金會管理。能夠實現Python語言的解釋器及編譯器有許多,包括Java版的Jython,不過在此簡要回顧中,咱們特指由Guido開發的C語言實現。
在Python官方網站上[python] ,您能夠找到該語言的許多教程、官方文檔以及庫指南。
若要獲取更多參考文獻,咱們推薦參考文獻[guido] 和 [lutz] 中的書。
若是您已經熟悉Python語言,能夠跳過本章節。
啓動
Web2py的二進制發行版支持微軟Windows或蘋果OS X操做系統,該發行文件中包含內置的Python解釋器。
在Windows操做系統下,可使用以下命令來啓動web2py(在DOS提示符下輸入):
web2py.exe -S welcome
在蘋果OS X操做系統下,在終端窗口中輸入以下命令(假如您與web2py.app在同一文件夾中):
./web2py.app/Contents/MacOS/web2py -S welcome
在Linux或其餘Unix操做系統下,極可能Python已經安裝過了,若是是這樣的話,在shell提示符下輸入:
python web2py.py -S welcome
若是您沒有預先安裝Python2.5(或者更新的版本2.x),在運行web2py以前,您須要下載並安裝新的Python。
• S welcome 命令行選項指示web2py運行交互式殼(shell),就像是welcome應用中命令在控制器內被執行,即web2py基本構建應用。這向用戶暴露了幾乎全部的web2py的類、對象及函數。這是web2py交互式命令行與普通Python命令行的惟一不一樣之處。
對於每一個應用,管理接口提供了一個基於web的shell。對於"welcome"應用,您能夠訪問shell。
http://127.0.0.1:8000/admin/shell/index/welcome
您可使用普通shell或基於web的shell來嘗試本章中的全部例子。
help, dir程序員

Python語言提供了兩條命令來獲取定義在當前做用域內對象的有關文檔,包括內置的和用戶定義的。
咱們能夠尋求有關對象的help,例如"1":web

help(1)
Help on int object:shell

class int(object)
| int(x[, base]) -> integer
|
| Convert a string or number to an integer, if possible. A floating point
| argument will be truncated towards zero (this does not include a string
| representation of a floating point number!) When converting a string, use
| the optional base. It is an error to supply a base when converting a
| non-string. If the argument is outside the integer range a long object
| will be returned instead.
|
| Methods defined here:
|
| abs(...)
| x.__abs__() <==> abs(x)
...
而且因爲"1"是一個整數,咱們獲得int類及其全部方法的描述。這裏輸出被截斷了,由於它很長很是詳細。
相似的,咱們用命令dir獲取對象"1"的方法列表:數據庫

dir(1)
['abs', 'add', 'and', 'class', 'cmp', 'coerce',
'delattr', 'div', 'divmod', 'doc', 'float',
'floordiv', 'getattribute', 'getnewargs', 'hash', 'hex',
'index', 'init', 'int', 'invert', 'long', 'lshift',
'mod', 'mul', 'neg', 'new', 'nonzero', 'oct',
'or', 'pos', 'pow', 'radd', 'rand', 'rdiv',
'rdivmod', 'reduce', 'reduce_ex', 'repr', 'rfloordiv',
'rlshift', 'rmod', 'rmul', 'ror', 'rpow', 'rrshift',
'rshift', 'rsub', 'rtruediv', 'rxor', 'setattr',
'str', 'sub', 'truediv', 'xor']
類型
Python是一種動態類型語言,這意味着變量沒有類型,所以也不須要被聲明。另外一方面,值是有類型的。您能夠查詢變量包含的值的類型:
a = 3
print type(a)
<type 'int'>
a = 3.14
print type(a)
<type 'float'>
a = 'hello python'
print type(a)
<type 'str'>
Python也包括了原生的數據結構,如列表和字典。
字符串編程

Python支持兩種不一樣類型字符串的使用:ASCII字符串和Unicode字符串。ASCII字符串使用'...'、"..." 、'..' 或 """..."""分隔。三重引號分隔多行字符串。Unicode字符串以一個u起始,包含Unicode字符的字符串跟在後面。經過選擇編碼,能夠將Unicode字符串轉換成ASCII字符串,例如:數組

a = 'this is an ASCII string'
b = u'This is a Unicode string'
a = b.encode('utf8')
執行完這三條命令以後,獲得的結果a是一個存儲UTF8編碼字符的ASCII字符串。按照設計,web2py內部使用UTF8編碼的字符串。
能夠用多種方法將變量寫入字符串:
print 'number is ' + str(3)
number is 3
print 'number is %s' % (3)
number is 3
print 'number is %(number)s' % dict(number=3)
number is 3
最後一種標記是首選,它更明確、不容易出錯。
使用str或repr命令,許多Python對象能夠被序列化成字符串,例如數字。這兩條命令很是類似,但會產生略有不一樣的輸出。例如:
for i in [3, 'hello']:
print str(i), repr(i)
3 3
hello 'hello'
對於用戶定義的類,使用特殊操做符__str__ 和__repr__,str和repr能夠被定義/重定義。後面會對此做簡要介紹;更多相關內容,請參閱Python官方文檔。repr總有一個默認值。
Python字符串的另外一重要特徵是,像列表同樣,它是一個遍歷對象。
for i in 'hello':
print i
h
e
l
l
o
列表
Python列表的主要方法包括添加(append)、插入(insert)、刪除(delete):
a = [1, 2, 3]
print type(a)
<type 'list'>
a.append(8)
a.insert(2, 7)
del a[0]
print a
[2, 7, 3, 8]
print len(a)
4
列表能夠被分片:
print a[:3]
[2, 7, 3]
print a[1:]
[7, 3, 8]
print a[-2:]
[3, 8]
還能夠被鏈接:
a = [2, 3]
b = [5, 6]
print a + b
[2, 3, 5, 6]
列表能夠被遍歷;能夠經過循環訪問:
a = [1, 2, 3]
for i in a:
print i
1
2
3
列表中的元素沒必要是相同類型;它們能夠是Python對象的任意類型。
有一種很常見的狀況,可使用列表解析(list comprehension)。請看以下代碼:
a = [1,2,3,4,5]
b = []
for x in a:
if x % 2 == 0:
b.append(x * 3)
b
[6, 12]
這段代碼清楚地處理了一個項目列表,選擇和修改了輸入列表的一個子表,並建立了一個新的結果列表。用下列列表解析,能夠徹底代替上述代碼:
a = [1,2,3,4,5]
b = [x * 3 for x in a if x % 2 == 0]
b
[6, 12]
元組
元組相似於列表,可是它的大小和元素是不可變的,而列表的大小和元素是可變的。若是元組元素是一個對象,則對象的屬性是可變的。元組由圓括號分隔。
a = (1, 2, 3)
所以,以下代碼適用於列表:
a = [1, 2, 3]
a[1] = 5
print a
[1, 5, 3]
元素賦值不能用於元組:
a = (1, 2, 3)
print a[1]
2
a[1] = 5
Traceback (most recent call last):
File " ", line 1, in
TypeError: 'tuple' object does not support item assignment
相似於列表,元組是一個遍歷對象。請注意,一個元素構成的元組必須包含一個結尾逗號,以下所示:
a = (1)
print type(a)
<type 'int'>
a = (1,)
print type(a)
<type 'tuple'>
因爲元組的不變性,對高效封裝對象,元組是很是有用的,並且括號每每是可選的。
a = 2, 3, 'hello'
x, y, z = a
print x
2
print z
hello
字典
Python字典是一個哈希表,將鍵對象映射成值對象。例如:
a = {'k':'v', 'k2':3}
a['k']
v
a['k2']
3
a.has_key('k')
True
a.has_key('v')
False
鍵能夠是任何哈希類型(整型、字符串,或類能實現_hash_方法的任何對象)。值能夠是任何類型。在同一字典中,不一樣鍵和值不必定是相同的類型。若是鍵是字母數字字符,也能用替代句法聲明字典:
a = dict(k='v', h2=3)
a['k']
v
print a
{'k':'v', 'h2':3}
實用的方法是has_key、 keys、values和items:
a = dict(k='v', k2=3)
print a.keys()
['k', 'k2']
print a.values()
['v', 3]
print a.items()
[('k', 'v'), ('k2', 3)]
Items方法產生一元組列表,每一個元組包含一個鍵和它的對應值。
字典元素和列表元素能夠用del命令刪除。
a = [1, 2, 3]
del a[1]
print a
[1, 3]
a = dict(k='v', h2=3)
del a['h2']
print a
{'k':'v'}
在內部,Python用hash運算符將對象轉換成整數,並用獲得的整數肯定值存儲在哪裏。
hash("hello world")
-1500746465
關於縮進
Python使用縮進分隔代碼塊。一個代碼塊起始於一行以冒號結尾的代碼,下面全部縮進相同或更多的行都被視爲同一個代碼塊。例如:
i = 0
while i < 3:
print i
i = i + 1
緩存

0
1
2
一般每級縮進使用四個空格。不混用tab和空格是一個好的策略,那樣可能會致使(不可見的)混亂。
for...in
在Python中,你能夠循環遍歷對象:
a = [0, 1, 'hello', 'python']
for i in a:
print i
0
1
hello
python
一種經常使用快捷方式是xrange,它能夠產生一個遍歷範圍而無需存儲整個列表元素。
for i in xrange(0, 4):
print i
0
1
2
3
這與C/C++/C#/Java句法是等價的:
for(int i=0; i<4; i=i+1) { print(i); }
另外一種實用的命令是enumerate,在循環的同時能計數:
a = [0, 1, 'hello', 'python']
for i, j in enumerate(a):
print i, j
0 0
1 1
2 hello
3 python
還有一個關鍵詞range(a,b,c)能夠返回一個整數列表,從值a開始,遞增c,結束值小於b,其中a的默認值是0,c的默認值是1。xrange與此相似,但不會真正生成列表,只生成一個列表的遍歷,所以對於循環來講它更好。 你可使用break跳出循環。
你可使用break跳出循環。
for i in [1, 2, 3]:
print i
break
1
使用continue,你能夠不執行完整個代碼塊就跳轉到下一個循環迭代。
for i in [1, 2, 3]:
print i
continue
print 'test'
1
2
3
while
在Python中,while循環的工做方式與其它語言相似,在執行循環體前先判斷循環次數和測試條件。若是條件爲假,循環就終止。
i = 0
while i < 10:
i = i + 1
print i
10
Python中沒有loop…until結構。
if...elif...else安全

在Python中使用條件是直觀的:數據結構

for i in range(3):
if i == 0:
print 'zero'
elif i == 1:
print 'one'
else:
print 'other'
zero
one
other
「elif」意味着 「else if」。elif和else從句都是可選的。能夠有多個elif語句,但只能有一個else聲明。使用not,and和or運算符能夠構造複雜條件。
for i in range(3):
if i == 0 or (i == 1 and i + 1 == 2):
print '0 or 1'
try...except...else...finally

Python能夠拋出中斷,引起異常:

try:
a = 1 / 0
except Exception, e:
print 'oops: %s' % e
else:
print 'no problem here'
finally:
print 'done'
oops: integer division or modulo by zero
done
若是引發異常,它會被except語句捕獲,except語句會被執行,而else語句不被執行。若是未引發異常,except語句不被執行,而else語句會被執行。finally語句始終會被執行。
對於可能出現的不一樣異常,能夠有多種except語句。
try:
raise SyntaxError
except ValueError:
print 'value error'
except SyntaxError:
print 'syntax error'
syntax error
else和finally語句都是可選的。
如下是Python內置異常+HTTP(由web2py定義)列表。
BaseException
+-- HTTP (defined by web2py)
+-- SystemExit
+-- KeyboardInterrupt
+-- Exception
+-- GeneratorExit
+-- StopIteration
+-- StandardError
| +-- ArithmeticError
| | +-- FloatingPointError
| | +-- OverflowError
| | +-- ZeroDivisionError
| +-- AssertionError
| +-- AttributeError
| +-- EnvironmentError
| | +-- IOError
| | +-- OSError
| | +-- WindowsError (Windows)
| | +-- VMSError (VMS)
| +-- EOFError
| +-- ImportError
| +-- LookupError
| | +-- IndexError
| | +-- KeyError
| +-- MemoryError
| +-- NameError
| | +-- UnboundLocalError
| +-- ReferenceError
| +-- RuntimeError
| | +-- NotImplementedError
| +-- SyntaxError
| | +-- IndentationError
| | +-- TabError
| +-- SystemError
| +-- TypeError
| +-- ValueError
| | +-- UnicodeError
| | +-- UnicodeDecodeError
| | +-- UnicodeEncodeError
| | +-- UnicodeTranslateError
+-- Warning
+-- DeprecationWarning
+-- PendingDeprecationWarning
+-- RuntimeWarning
+-- SyntaxWarning
+-- UserWarning
+-- FutureWarning
+-- ImportWarning
+-- UnicodeWarning
關於以上列表中每一項的詳細介紹,請參閱Python官方文檔。
web2py僅暴露一個新異常,該異常被稱做HTTP。當該異常出現時,它會使程序返回一個HTTP錯誤頁面(更多相關內容請參閱第4章)
任何對象均可以引發異常,但推薦的作法是引發異常的對象是內置異常類的擴展。
def...return

函數聲明使用def。下面是一個典型的Python函數:

def f(a, b):
return a + b
print f(4, 2)
6
沒有必要(或者方法)指定參數類型或返回類型。這個例子中,定義了一個有兩個參數的函數f。
函數是本章描述的第一個代碼句法特徵,這是爲了引入域和命名空間的概念。在上面的例子中,標識符a和b在函數f的域以外是沒有定義的:
def f(a):
return a + 1
print f(1)
2
print a
Traceback (most recent call last):
File "<pyshell#22>", line 1, in
print a
NameError: name 'a' is not defined
定義在函數域以外的標識符是能夠在函數內訪問的;請觀察在下面代碼中標識符a是如何被處理的:
a = 1
def f(b):
return a + b
print f(1)
2
a = 2
print f(1) # new value of a is used
3
a = 1 # reset a
def g(b):
a = 2 # creates a new local a
return a + b
print g(2)
4
print a # global a is unchanged
1
若是a被修改了,隨後的函數調用將使用全局變量a的新值,由於函數定義綁定了標識符a的存儲位置,而不是在函數聲明時標識符a自己的值;可是,若是a被分配到函數g內,全局變量a將不會受影響由於新的局部變量a覆蓋了全局變量的值。在建立閉包(closure)時,可使用外部域參考。
def f(x):
def g(y):
return x * y
return g
doubler = f(2) # doubler is a new function
tripler = f(3) # tripler is a new function
quadrupler = f(4) # quadrupler is a new function
print doubler(5)
10
print tripler(5)
15
print quadrupler(5)
20
函數f會建立新函數;而且注意名稱g的域徹底在f內部。閉包是很是強大的。
函數參數能夠有默認值,而且可以返回多個結果。
def f(a, b=2):
return a + b, a - b
x, y = f(5)
print x
7
print y
3
利用函數名,函數參數能夠被顯式傳遞,這意味着在函數調用中指定的參數順序能夠不一樣於函數定義時的參數順序:
def f(a, b=2):
return a + b, a - b
x, y = f(b=5, a=2)
print x
7
print y
-3
函數也能取一個運行時可變數目的參數:
def f(*a, **b):
return a, b
x, y = f(3, 'hello', c=4, test='world')
print x
(3, 'hello')
print y
{'c':4, 'test':'world'}
這裏在元組a中存儲的參數沒有被(3, ’hello’)傳遞,而字典b中存儲的參數被(c 和 test)傳遞。
在相反的狀況下,將一個列表或元組傳遞給函數,它須要經過拆分獲得單個位置參數。
def f(a, b):
return a + b
c = (1, 2)
print f(*c)
3
而且能夠將字典拆分傳遞關鍵詞參數。
def f(a, b):
return a + b
c = {'a':1, 'b':2}
print f(**c)
3
lambda
lambda提供了一種建立很是短的未命名函數的簡易方法:
a = lambda b: b + 2
print a(3)
5
表達式"lambda [a]:[b]" 直譯爲「一個帶參數[a] 返回[b]的函數」。lambda表達式自己是匿名的,可是該函數經過綁定標識符a得到了名稱。def的域規則一樣適用於lambda,實際上就a而言,上面的代碼等同於使用 def的函數聲明:
def a(b):
return b + 2
print a(3)
5
lambda惟一的優勢是簡潔;然而,在特定狀況下簡潔是十分方便的。考慮一個名爲map的函數,它對列表中的全部項應用一個函數來建立一個新列表:
a = [1, 7, 2, 5, 4, 8]
map(lambda x: x + 2, a)
[3, 9, 4, 7, 6, 10]
在上面的代碼中,若是使用def取代lambda,代碼將擴大一倍。lambda的主要缺點是(在Python實現下)句法只容許一個單一表達式;然而對於更長的函數可使用def,由於提供函數名的額外成本隨着函數長度增長而減小。同def同樣,lambda也可用來curry函數:能夠經過封裝已有函數建立新函數,這樣新函數就會攜帶一組不一樣的參數。
def f(a, b): return a + b
g = lambda a: f(a, 3)
g(2)
5
不少狀況下curry功能是有用的,其中一種在web2py中是直接有用的:緩存(caching)。 假設你有一個高負荷函數,檢查參數是否爲素數:
def isprime(number):
for p in range(2, number):
if (number % p) == 0:
return False
return True
該函數明顯是耗時的。
假設你有一個緩存函數cache.ram,它帶有3個參數:鍵、函數和秒數。
value = cache.ram('key', f, 60)
該函數初次被調用時,它將調用函數f(),在內存中的字典裏保存輸出(比方說「d」),而且返回它,所以值(value)是:
value = d['key']=f()
該函數第二次被調用時,若是鍵在字典中,並且存在的時間很少於指定的秒數(60),它將返回相應的值而不執行函數調用。
value = d['key']
對任意輸入,如何緩存函數isprime的輸出呢?這裏是一種方法:
number = 7
seconds = 60
print cache.ram(str(number), lambda: isprime(number), seconds)
True
print cache.ram(str(number), lambda: isprime(number), seconds)
True
輸出老是同樣的,可是cache.ram第一次被調用時,isprime會被調用;第二次時,就不調用了。
使用def或lambda建立的Python函數,容許根據不一樣參數組重構已有函數。 cache.ram和cache.disk是web2py緩存函數。

由於Python是動態類型,Python類和對象彷佛有點異樣。事實上,當聲明類時不須要定義成員變量(屬性),並且同一個類的不一樣實例能夠有不一樣屬性。屬性一般與實例相關,而不是類(除了被聲明爲類屬性,這與C++/Java中的靜態成員變量是同樣的)。
下面是一個例子:
class MyClass(object): pass
myinstance = MyClass()
myinstance.myvariable = 3
print myinstance.myvariable
3
注意pass是一條不做任何操做的命令。在本例中它被用來定義MyClass()類,該類不包含任何內容。MyClass()調用類構造函數(在本例中是默認構造),並返回一個對象,即類的一個實例。在類定義中,(object)代表咱們的類擴展內置的object類。這不是必需的,但這是好的作法。
下面是一個更復雜的類:
class MyClass(object):
z = 2
def init(self, a, b):
self.x = a, self.y = b
def add(self):
return self.x + self.y + self.z
myinstance = MyClass(3, 4)
print myinstance.add()
9
在類中被聲明的函數是方法。有些方法有特殊的保留名稱,例如, init 是構造。除了方法外聲明的變量,其他全部變量都是方法的局部變量。例如, z 是一個類變量,等同於一個C++中的靜態成員變量,該變量對類的全部實例保持相同的值。
注意 init 帶有3個參數, add 帶有1個參數,但咱們分別用2個和0個參數調用它們。按照慣例,第一個參數表示方法內部使用的指示當前對象的局部名稱。這裏咱們用 self 指示當前對象,但也可使用其它名稱。 self 起到相同的做用,正像 this 在C++中或者 this 在Java中同樣,但self不是保留的關鍵詞。
當聲明嵌套類的時候,爲了不歧義採起這種句法是有必要的,例如一個類在另外一個類中是局部方法。
特殊屬性、方法、運算符
以雙下劃線開頭的類屬性、方法和運算符一般被視做私有的(即在內部使用但不暴露在類的外部),雖然這是一種慣例,但解釋器並不強制。
其中有些是保留關鍵詞,並具備特別含義。
其中3個例子是:
len
getitem
setitem
例如,能夠用它們建立一個功能相似於列表的容器對象:
class MyList(object):
def init(self,
a): self.a = list(a)
def len(self): return len(self.a)
def getitem(self, i): return self.a[i]
def setitem(self, i, j): self.a[i] = j
b = MyList(3, 4, 5)
print b[1]
4
b.a[1] = 7
print b.a
[3, 7, 5]
其它特殊運算符包括 getattrsetattrsumsub ,前兩個定義類的get和set屬性,後兩個重載了算數運算符。關於這些運算符的使用,咱們向讀者推薦這一主題的更深的書籍。前面咱們已經提到了特殊運算符 strrepr
文件輸入/輸出

在Python中,你能夠用以下代碼打開和寫入文件:

file = open('myfile.txt', 'w')
file.write('hello world')
file.close()
相似的,你能夠用以下代碼讀文件:
file = open('myfile.txt', 'r')
print file.read()
hello world
另外,你可使用標準C標記,用 "rb" 在二進制模式下讀取,用"wb"在二進制模式下寫入,用"a"在附加模式下打開文件。
read命令有一個可選參數,它是字節數。你還能夠在文件中用seek跳轉到任意位置。
你能夠用read讀取文件,
print file.seek(6)
print file.read()
world
並且你能夠用以下方法關閉文件:
file.close()
在Python標準發行版被稱爲CPython,變量是引用計數的,包括那些持有的文件句柄,因此當一個打開文件句柄的引用計數減小到0時,CPython是知道的,這時就能夠關閉文件和處理變量。然而,在Python的其它實現如PyPy中,使用垃圾回收取代引用計數,這意味着同一時間內可能積聚過多的打開文件句柄,在gc有機會關閉和處理它們以前致使錯誤。所以,當再也不須要的時候,最好明確關閉文件句柄。web2py在gluon.fileutils 命名空間內提供兩個幫助函數read_file() 和 write_file(),它們封裝文件訪問,並確保正在實用的文件句柄被正確關閉。
在使用web2py時,你不能肯定當前目錄的位置,由於這依賴於web2py的配置。變量request.folder包含了當前應用的路徑。使用os.path.join命令能夠級聯路徑,將在後面討論。
exec, eval

與Java不一樣,Python是真正的解釋型語言。這意味着它能執行存儲在字符串中的Python語句。例如:

a = "print 'hello world'"
exec(a)
'hello world'
發生了什麼呢?exec函數告訴解釋器調用它,執行參數傳遞的字符串的內容。它也能夠執行詞典中的符號定義的範圍內的一個字符串的內容。
a = "print b"
c = dict(b=3)
exec(a, {}, c)
3
當執行字符串 a 時,這裏解釋器看到定義在 c 中的符號(本例中是 b ),但不能看到 c 或 a 自己。這與受限環境不一樣,由於 exec 不限制內部代碼能夠作什麼;它只是定義了一組代碼可見的變量。
與此相關的函數是eval,它的工做方式很是像exec,除了它期待參數能計算獲得一個值,而且它將返回這個值。
a = "3*4"
b = eval(a)
print b
12
import

Python真正的強大之處是它的庫模塊。這些模塊對許多系統庫提供了一組大量的、一致性的應用編程接口(以一種獨立於操做系統的方式)。
例如,若是你須要使用一個隨機數生成器,能夠採用以下方法:

import random
print random.randint(0, 9)
5
它會打印一個0到9之間(包括9)的隨機數,本例中是5。randint函數是定義在模塊random中的。它也能夠未來自模塊的一個對象導入到當前命名空間:
from random import randint
print randint(0, 9)
或者未來自模塊的所有對象導入到當前命名空間:
from random import *
print randint(0, 9)
或者將所有內容導入新定義的命名空間:
import random as myrand
print myrand.randint(0, 9)
在本書的其他部分,咱們將主要使用定義在 os ,sys , datetime 和 cPickle 模塊中的對象。
經過膠子(gluon)模塊能夠訪問所有web2py對象,這是後面章節中的主題。web2py在內部使用許多Python模塊(例如thread),但你不多須要直接訪問它們。
在如下小節中,咱們介紹幾個最實用的模塊。
os

這個模塊提供了一個操做系統API接口。例如:

import os
os.chdir('..')
os.unlink('filename_to_be_deleted')
一些os函數千萬不能用在web2py中,由於它們不是線程安全的,例如chdir。
os.path.join是很是實用的;它容許以獨立於操做系統的方式級聯路徑:
import os
a = os.path.join('path', 'sub_path')
print a
path/sub_path
經過以下方法,能夠訪問系統環境變量:
print os.environ
這是一個只讀字典。
sys

sys 模塊包含許多變量和函數,咱們使用最多的一個是sys.path 。它包含了一個路徑列表,Python在那裏搜索模塊。當咱們試圖導入一個模塊時,Python會在 sys.path 列出的全部文件夾中查找。若是你在一些位置安裝額外模塊,而且但願Python能找到它們,你須要將到那個地址的路徑附加到 sys.path 中。

import sys
sys.path.append('path/to/my/modules')
在運行web2py時,Python常駐在內存中,而且只有一個 sys.path ,然而有多個線程爲HTTP請求服務。爲了不內存泄露,在添加路徑前,最好先檢查一下該路徑是否已經存在。
path = 'path/to/my/modules'
if not path in sys.path:
sys.path.append(path)
datetime

datetime模塊的使用最好經過例子來講明:

import datetime print datetime.datetime.today() 2008-07-04 14:03:90 print datetime.date.today() 2008-07-04 有時你須要的時間戳數據多是基於UTC時間,而不是本地時間。在這種狀況下,你可使用以下函數: import datetime print datetime.datetime.utcnow() 2008-07-04 14:03:90 datetime模塊包含各類類:date,datetime,time和timedelta。兩個date或兩個datetime或兩個time對象之間的區別就是timedelta。 a = datetime.datetime(2008, 1, 1, 20, 30) b = datetime.datetime(2008, 1, 2, 20, 30) c = b - a print c.days 1 在web2py中,當傳遞到數據庫或從數據庫中返回時,date和datetime可用於存儲相應的SQL類型。 time time模塊不一樣於 date 和 datetime ,由於它表示的時間是從紀元(從1970年開始)開始的秒數。 import time t = time.time() 1215138737.571 關於用秒錶示的時間和用 datetime 表示的時間之間的轉換函數,請參閱Python文檔。 cPickle 這是一個很是強大的模塊。它提供的函數能夠序列化幾乎全部Python對象,包括自引對象。例如,讓咱們構建一個特殊的對象: class MyClass(object): pass myinstance = MyClass() myinstance.x = 'something' a = [1 ,2, {'hello':'world'}, [3, 4, [myinstance]]] 如今: import cPickle b = cPickle.dumps(a) c = cPickle.loads(b) 本例中,b是一個a的字符串表示,c是一個經過反序列化b產生的a的副本。 cPickle也能夠序列化到文件和從文件反序列化; cPickle.dump(a, open('myfile.pickle', 'wb')) c = cPickle.load(open('myfile.pickle', 'rb'))

相關文章
相關標籤/搜索