在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ Python/ 表達式
附錄
進程通信
操作系統(tǒng)
迭代器
模塊
描述符
裝飾器
第三部分 擴展庫
內(nèi)置類型
數(shù)據(jù)存儲
數(shù)據(jù)類型
基本環(huán)境
文件與目錄
異常
程序框架
數(shù)學運算
函數(shù)
元類
字符串
表達式

表達式

句法規(guī)則

Python 源碼格式有點特殊。首先,可能因為出生年代久遠的緣故,編譯器默認編碼采用 ASCII,而非當前通行的 UTF-8。其次,就是強制縮進格式讓很多人 "糾結(jié)",甚至 "望而卻步"。

源文件編碼

下面這樣的錯誤,初學時很常見。究其原因,還是編譯器默認將文件當成 ASCII 碼的緣故。

SyntaxError: Non-ASCII character '\xe4' in file ./main.py on line 4, but no encoding
declared; see http://www.python.org/peps/pep-0263.html for details

解決方法:在文件頭部添加正確的編碼標識。

$ cat main.py
#/usr/bin/env python
# coding=utf-8

def main():
    print "世界末日!"   # 瑪雅人都是騙人的

if __name__ == "__main__":
    main()

也可以寫成:

# -*- coding:utf-8 -*-

強制縮進

縮進是強制性的語法規(guī)則。通常建議用 4 個空格代替 TAB,好在多數(shù)編輯器都能自動轉(zhuǎn)換。

最大的麻煩就是從網(wǎng)頁拷貝代碼時,縮進丟失導致源碼成了亂碼。解決方法是:

  • 像很多 C 程序員那樣,在 block 尾部添加 "# end" 注釋。
  • 如果嫌不好看,可自定義一個 end 偽關(guān)鍵字。
#/usr/bin/env python
# coding=utf-8

__builtins__.end = None  # 看這里,看這里……

def test(x):
    if x > 0:
        print "a"
    else:
        print "b"
    end
end

def main():
    print "世界末日!"   # 再次鄙視瑪雅人!(*_*)
end

if __name__ == "__main__":
    main()

只要找到 end,就能確定 code block 的縮進范圍了。

注釋

注釋從 # 開始,到行尾結(jié)束,不支持跨行。大段的描述可以用 """doc"""。

語句

可以用 ";" 將多條語句寫在同一行,或者用 "\" 將一條語句拆分成多行。

>>> d = {}; d["a"] = 1; d.items()
[('a', 1)]

>>> for k, v in \
... d.items():
... print k, v

a 1

某些 ()、[]、{} 表達式無需 "\" 就可寫成多行。

>>> d = {
...     "a": 1,
...     "b": 2
... }

>>> d.pop("a",
... 2)
1

幫助

可以非常方便地為函數(shù)、模塊和類添加幫助信息。

>>> def test():
...     """
...     func help
...     """
...     pass

>>> test.__doc__
'\n     func help\n '

>>> class User(object):
...     """User Model"""
...
...     def __init__(self):
...         """user.__init__"""
...         pass

>>> User.__doc__
'User Model'

>>> User.__init__.__doc__
'user.__init__'

在 shell 用 help() 查看幫助信息,它會合并對象所有成員的幫助內(nèi)容。

命名規(guī)則

命名規(guī)則不算復(fù)雜,只不過涉及私有成員命名時有點講究。

  • 必須以字母或下劃線開頭,且只能是下劃線、字母和數(shù)字的組合。
  • 不能和語言保留字相同。
  • 名字區(qū)分大小寫。
  • 模塊中以下劃線開頭的名字視為私有。
  • 以雙下劃線開頭的類成員名字視為私有。
  • 同時以雙下劃線開頭和結(jié)尾的名字,通常是特殊成員。
  • 單一下劃線代表最后表達式的返回值。
>>> s = set("abc")
>>> s.pop()
'a'
>>> _
'a'

保留字 (包括 Python 3):

False       class       finally         is          return
None        continue    for             lambda      try
True        def         from            nolcoal     while
and         del         global          not         with
as          elif        if              or          yield
assert      else        import          pass
break       except      in              raise

賦值

除非在函數(shù)中使用關(guān)鍵字 global、nolocal 指明外部名字,否則賦值語句總是在當前名字空間創(chuàng)建或修改 {name:object} 關(guān)聯(lián)。

與 C 以 block 為隔離,能在函數(shù)中創(chuàng)建多個同名變量不同,Python 函數(shù)所有代碼共享同一名字空間,會出現(xiàn)下面這樣的狀況。

>>> def test():
...     while True:
...         x = 10
...         break
...     print locals()
...     print x   # 這個寫法在 C 里面會報錯。

>>> test()
{'x': 10}
10

支持用序列類型或迭代器對多個名字同時賦值。

>>> a, b = "a", "b"
>>> a, b = "ab"
>>> a, b = [1, 2]
>>> a, b = xrange(2)

一旦值多過名字數(shù)量,會引發(fā)異常。要么切片,要么用 "_" 補位。

>>> a, b = "abc"
Traceback (most recent call last):
    a, b = "abc"
ValueError: too many values to unpack

>>> a, b, _ = "abc"

>>> a, b = "abc"[:2]

Python 3 對此提供了更好的支持。

Python 3.3.0 (default, Nov 4 2012, 20:26:43)

>>> a, *b, c = "a1234c"
>>> a, b, c
('a', ['1', '2', '3', '4'], 'c')

表達式

if

只需記住將 "else if" 換成 "elif" 即可。

>>> x = 10

>>> if x > 0:
...     print "+"
... elif x < 0:
...     print "-"
... else:
...     print "0"

+

可以改造得簡單一些。

>>> x = 1
>>> print "+" if x > 0 else ("-" if x < 0 else "0")
+

>>> x = 0
>>> print "+" if x > 0 else ("-" if x < 0 else "0")
0

>>> x = -1
>>> print "+" if x > 0 else ("-" if x < 0 else "0")
-

或者利用 and、or 條件短路,寫得更簡潔些。

>>> x = 1
>>> print (x > 0 and "+") or (x < 0 and "-") or "0"
+

>>> x = 0
>>> print (x > 0 and "+") or (x < 0 and "-") or "0"
0

>>> x = -1
>>> print (x > 0 and "+") or (x < 0 and "-") or "0"
-

可以將兩次比較合并成一個表達式。

>>> x = 10
>>> if (5 < x <= 10): print "haha"
haha!

條件表達式不能包含賦值語句,習慣此種寫法的需要調(diào)整一下了。

>>> if (x = 1) > 0: pass
    File "<ipython-input-4-bc2d73931d91>", line 1
        if (x = 1) > 0: pass
            ^
SyntaxError: invalid syntax

while

比我們熟悉的 while 多了個可選的 else 分支。如果循環(huán)沒有被中斷,那么 else 就會執(zhí)行。

>>> x = 3

>>> while x > 0:
...     x -= 1
... else:
...     print "over"

over!

>>> while True:
...     x += 1
...     if x > 3: break
... else:
...     print "over"

利用 else 分支標記循環(huán)邏輯被完整處理是個不錯的主意。

for

更名為 foreach 可能更合適一些,用來循環(huán)處理序列和迭代器對象。

>>> for i in xrange(3): print i
0
1
2

>>> for k, v in {"a":1, "b":2}.items(): print k, v # 多變量賦值
a 1
b 2

>>> d = ((1, ["a", "b"]), (2, ["x", "y"]))

>>> for i, (c1, c2) in d:    # 多層展開
... print i, c1, c2
1 a b
2 x y

同樣有個可選的 else 分支。

>>> for x in xrange(3):
...     print x
... else:
...     print "over"

0
1
2
over!

>>> for x in xrange(3):
...     print x
...     if x > 1: break
... else:
...     print "over"

0
1
2

要實現(xiàn)傳統(tǒng)的 for 循環(huán),需要借助 enumerate() 返回序號。

>>> for i, c in enumerate("abc"):
... print "s[{0}] = {1}".format(i, c)

s[0] = a
s[1] = b
s[2] = c

pass

占位符,用來標記空代碼塊。

>>> def test():
...     pass

>>> class User(object):
...     pass

break / continue

break 中斷循環(huán),continue 開始下一次循環(huán)。

沒有 goto、label,也無法用 break、continue 跳出多層嵌套循環(huán)。

>>> while True:
...     while True:
...         flag = True
...         break
...     if "flag" in locals(): break

如果嫌 "跳出標記" 不好看,可以考慮拋出異常。

>>> class BreakException(Exception): pass

>>> try:
...     while True:
...         while True:
...             raise BreakException()
... except BreakException:
...     print "越獄成功"

其實也沒好看到哪去,但好歹保持內(nèi)部邏輯的干凈。

del

可刪除名字、序列元素、字典鍵值,以及對象成員。

>>> x = 1
>>> "x" in globals()
True

>>> del x
>>> "x" in globals()
False

>>> x = range(10)
>>> del x[1]
>>> x
[0, 2, 3, 4, 5, 6, 7, 8, 9]

>>> x = range(10)
>>> del x[1:5]     # 按切片刪除
>>> x
[0, 5, 6, 7, 8, 9]

>>> d = {"a":1, "b":2}
>>> del d["a"]     # key 不存在時,會拋出異常。
>>> d
{'b': 2}

>>> class User(object): pass

>>> o = User()
>>> o.name = "user1"
>>> hasattr(o, "name")
True

>>> del o.name
>>> hasattr(o, "name")
False

Generator

用一種優(yōu)雅的方式創(chuàng)建列表、字典或集合。

>>> [x for x in range(10)]   # 列表
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

>>> {x for x in range(10)}   # 集合
set([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

>>> {c:ord(c) for c in "abc"}   # 字典
{'a': 97, 'c': 99, 'b': 98}

>>> (x for x in range(10))
<generator object <genexpr> at 0x10328a690>

可帶上條件進行過濾。

>>> [x for x in range(10) if x % 2]
[1, 3, 5, 7, 9]

或用多個 for 子句實現(xiàn)嵌套。

>>> ["{0}{1}".format(c, x) for c in "abc" for x in range(3)]
['a0', 'a1', 'a2', 'b0', 'b1', 'b2', 'c0', 'c1', 'c2']

這相當于:

>>> n = []
>>> for c in "abc":
...     for x in range(3):
...         n.append("{0}{1}".format(c, x))

每個子句都可有條件表達式,內(nèi)層可引用外層名字。

>>> ["{0}{1}".format(c, x)   \
...     for c in "aBcD" if c.isupper() \
...     for x in range(5) if x % 2  \
... ]
['B1', 'B3', 'D1', 'D3']

甚至可直接用做函數(shù)實參。

>>> def test(it):
...     for i, x in enumerate(it):
...         print "{0} = {1}".format(i, x)

>>> test(hex(x) for x in range(3))
0 = 0x0
1 = 0x1
2 = 0x2

運算符

這東西沒啥好說的,只要記得沒 "++"、"--" 就行。

http://wiki.jikexueyuan.com/project/the-python-study-notes-second-edition/images/1.png" alt="" />

http://wiki.jikexueyuan.com/project/the-python-study-notes-second-edition/images/2.png" alt="" />

切片

序列類型支持 "切片 (slice)" 操作,可通過兩個索引序號獲取片段。

>>> x = range(10)

>>> x[2:6]   # [2, 6)
[2, 3, 4, 5]

>>> x[2:-2]   # [2, len(x) - 2)
[2, 3, 4, 5, 6, 7]

支持大于 1 的步進。

>>> x[2:6:2]
[2, 4]

可以忽略起始或結(jié)束序號。

>>> x[:]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

>>> x[:6]
[0, 1, 2, 3, 4, 5]

>>> x[7:]
[7, 8, 9]

支持倒序。

>>> x[::-1]
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

>>> x[7:3:-2]
[7, 5]

可按切片范圍刪除序列元素。

>>> x = range(10)
>>> del x[4:8]; x
[0, 1, 2, 3, 8, 9]

>>> x = range(10)
>>> del x[::2]; x
[1, 3, 5, 7, 9]

甚至不等長的切片替換。

>>> a = [1, 2, 3]
>>> a[:1] = ["a", "b", "c"]

>>> a
['a', 'b', 'c', 2, 3]

布爾 and 返回短路時的最后一個值,or 返回第一個真值。要是沒短路的話,返回最后一個值。

>>> 1 and 2   # True: 最后一個值
2

>>> 1 and 2 and 0  # False: 最后一個值
0

>>> 1 and 0 and 2  # False: 第一個短路值 0
0

>>> 1 or 0   # True: 第一個真值 1
1

>>> 0 or [] or 1  # True: 第一個真值 1
1

>>> 0 or 1 or ["a"] # True: 第一個真值 1
1

用 and、or 實現(xiàn) "三元表達式 (:)"。

>>> x = 5
>>> print x > 0 and "A" or "B"
A

用 or 提供默認值。

>>> x = 5
>>> y = x or 0
>>> y
5

>>> x = None
>>> y = x or 0
>>> y
0

相等

操作符 "==" 可被重載,不適合用來判斷兩個名字是否指向同一對象。

>>> class User(object):
...     def __init__(self, name):
...         self.name = name
...     def __eq__(self, o):
...         if not o or not isinstance(o, User): return False
...          return cmp(self.name, o.name) == 0

>>> a, b = User("tom"), User("tom")
>>> a is b   # is 總是判斷指針是否相同。
False

>>> a == b   # 通過 __eq__ 進行判斷。
True

類型轉(zhuǎn)換

各種類型和字符串間的轉(zhuǎn)換。

>>> str(123), int('123')     # int
>>> bin(17), int('0b10001', 2)
>>> oct(20), int('024', 8)
>>> hex(22), int('0x16', 16)

>>> str(0.9), float("0.9")    # float

>>> ord('a'), chr(97), unichr(97)   # char

>>> str([0, 1, 2]), eval("[0, 1, 2]")   # list

>>> str((0, 1, 2)), eval("(0, 1, 2)")   # tuple

>>> str({"a":1, "b":2}), eval("{'a': 1, 'b': 2}") # dict

>>> str({1, 2, 3}), eval("{1, 2, 3}")   # set

常用函數(shù)

print

Python 2.7 可使用 print 表達式,Python 3 就只能用函數(shù)了。

>>> import sys

>>> print >> sys.stderr, "Error", 456
Error 456

>>> from __future__ import print_function

>>> print("Hello", "World", sep = ",", end = "\r\n", file = sys.stdout)
Hello,World

用標準庫中的 pprint.pprint() 代替 print,能看到更漂亮的輸出結(jié)果。要輸出到 /dev/null,可以使用 open(os.devnull, "w")。

input

input 會將輸入的字符串進行 eval 處理,raw_input 直接返回用戶輸入的原始字符串。

>>> input("$ ")
$ 1+2+3
6

>>> raw_input("$ ")
$ 1+2+3
'1+2+3'

Python 3 已經(jīng)將 raw_input 重命名為 input。

用標準庫 getpass 輸入密碼。

>>> from getpass import getpass, getuser

>>> pwd = getpass("%s password: " % getuser())
yuhen password:

>>> pwd
'123456'

exit

exit([status]) 調(diào)用所有退出函數(shù)后終止進程,并返回 ExitCode。

  • 忽略或 status = None,表示正常退出, ExitCode = 0。
  • status = ,表示 ExiCode = 。
  • 返回非數(shù)字對象表示失敗,參數(shù)會被顯示, ExitCode = 1。
$ cat main.py

#/usr/bin/env python
#coding=utf-8

import atexit

def clean():
    print "clean..."
def main():
    atexit.register(clean)
    exit("Failure")
if __name__ == "__main__":
    main()

$ ./main.py
Failure
clean...

$ echo $
1

sys.exit() 和 exit() 完全相同。os._exit() 直接終止進程,不調(diào)用退出函數(shù),且退出碼必須是數(shù)字。

vars

獲取 locals 或指定對象的名字空間。

vars() is locals() True

import sys

vars(sys) is sys.dict True

dir

獲取 locals 名字空間中的所有名字,或指定對象所有可訪問成員 (包括基類)。

>>> set(locals().keys()) == set(dir())
True
上一篇:文件與目錄下一篇:進程通信