Python

 

 
 

Python 內建函式

python-builtinifunction
 

class

類別 (class) 用來設計自己需要的物件 (object) ,這是說,類別是物件的模板。
Python 中設計類別使用關鍵字 (keyword) class ,
裡頭可定義類別的類別屬性 (class attribute) 、實體屬性 (instance attribute) 與方法 (method)
 
__ init __() 在 Python 類別 (class) 定義中是個特別的方法 (method) ,
因為這個方法是在物件 (object) 建立的時候執行的,如同其他物件導向程式語言 所講的建構子 (constructor)
 
舉例

class Encrypt(object):
    '''
    '''
    def __init__(self):
        '''
        '''
        self.code = [chr(i) for i in range(97, 123)]
        random.shuffle(self.code)
    def setCode(self, data):
        '''
        '''
        self.code = list(data)
...

def 方法(method)
self.code 實體屬性

 

class Dog:

    def __init__(self, name):
        self.name = name
        self.tricks = []    # creates a new empty list for each dog

    def add_trick(self, trick):
        self.tricks.append(trick)

>>> d = Dog('Fido')
>>> e = Dog('Buddy')
>>> d.add_trick('roll over')
>>> e.add_trick('play dead')
>>> d.tricks
['roll over']

>>> e.tricks
['play dead']

 

Common Sequence Operations

Operation Result
x in s True if an item of s is equal to x, else False
s + t the concatenation of s and t
s[i] ith item of s, origin 0
s[i:j] slice of s from i to j
s[i:j:k] slice of s from i to j with step k
len(s) length of s
min(s) smallest item of s
max(s) largest item of s
s.index(x) index of the first occurrence of x in s
s.count(x) total number of occurrences of x in s

 

List

有序的物件集合,具有索引特性,長度可以變動。
要建立串列,可以使用[]實字,串列中每個元素,使用逗號區隔。

my_list = [1, 2, 3, 4, 5, "aa", "bb"]
>>> my_list[1:3]
[2, 3]

>>> my_list[:-1]
[1, 2, 3, 4, 5, 'aa']

>>> my_list[:]
[1, 2, 3, 4, 5, 'aa', 'bb']

 
Operation Result
list.append(x) Add an item to the end of the list
list.extend(L) Extend the list by appending all the items in the given list
list.insert(i, x) Insert an item at a given position
list.remove(x) Remove the first item from the list whose value is x
list.pop([i]) Remove the item at the given position in the list, and return it. If no index is specified, a.pop() removes and returns the last item in the list.
list.index(x) Return the index in the list of the first item whose value is x
list.count(x) Return the number of times x appears in the list
list.sort() Sort the items of the list in place
list.reverse() Reverse the elements of the list, in place

 

>>> a = [66.25, 333, 333, 1, 1234.5]
>>> print a.count(333), a.count(66.25), a.count('x')
2 1 0

>>> a.insert(2, -1)
>>> a.append(333)
>>> a
[66.25, 333, -1, 333, 1, 1234.5, 333]

>>> a.index(333)
1

>>> a.remove(333)
>>> a
[66.25, -1, 333, 1, 1234.5, 333]

>>> a.reverse()
>>> a
[333, 1234.5, 1, 333, -1, 66.25]

>>> a.sort()
>>> a
[-1, 1, 66.25, 333, 333, 1234.5]

>>> a.pop()
1234.5

>>> a
[-1, 1, 66.25, 333, 333]

>>> a.pop(1)
1

>>> a
[-1, 66.25, 333, 333]

 
List Comprehensions

[ str(i) for i in xrange(4) if i > 0 ]
 

>>> self.hostIndex = {'node1':'192.168.10.51', 'node2':'192.168.10.52', 'center':'192.168.10.50'}
>>> hosts = [ h for h in self.hostIndex.keys() ]
>>> hosts
[node1, node2, center]

 

Set

集合(Set)是無序、元素不重複的集合。
以下範例是Python 3的版本

>>> basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'}
>>> print(basket)                      # show that duplicates have been removed
{'orange', 'banana', 'pear', 'apple'}

>>> 'orange' in basket                 # fast membership testing
True

>>> 'crabgrass' in basket
False
>>> a = set('abracadabra')
>>> b = set('alacazam')
>>> a                                  # unique letters in a
{'a', 'r', 'b', 'c', 'd'}

>>> a - b                              # letters in a but not in b
{'r', 'd', 'b'}

>>> a | b                              # letters in either a or b
{'a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'}

>>> a & b                              # letters in both a and b
{'a', 'c'}

>>> a ^ b                              # letters in a or b but not both
{'r', 'd', 'b', 'm', 'z', 'l'}

 

Dictionary

字典物件是儲存鍵(Key)/值(Value)對應的物件

>>> tel = {'jack': 4098, 'sape': 4139}
>>> tel['guido'] = 4127
>>> tel
{'sape': 4139, 'guido': 4127, 'jack': 4098}

>>> tel['jack']
4098

>>> del tel['sape']
>>> tel['irv'] = 4127
>>> tel
{'guido': 4127, 'irv': 4127, 'jack': 4098}

>>> list(tel.keys())
['irv', 'guido', 'jack']

>>> sorted(tel.keys())
['guido', 'irv', 'jack']

>>> 'guido' in tel
True

>>> 'jack' not in tel
False

 
Dictionary Operations

dict.iterkeys()

Returns an iterator over the dictionary’s keys.

 
del dict[key]
Remove dict[key] from dict.

 
dict.keys()
Return a new view of the dictionary’s keys.

 

Control Flow Tools

if Statements

>>> x = int(input("Please enter an integer: "))
Please enter an integer: 42

>>> if x < 0:
...     x = 0
...     print('Negative changed to zero')
... elif x == 0:
...     print('Zero')
... elif x == 1:
...     print('Single')
... else:
...     print('More')

 
for Statements
>>> # Measure some strings:
... words = ['cat', 'window', 'defenestrate']

>>> for w in words:
...     print(w, len(w))
...

cat 3
window 6
defenestrate 12

 
Defining Functions
>>> def fib(n):    # write Fibonacci series up to n
...     """Print a Fibonacci series up to n."""
...     a, b = 0, 1
...     while a < n:
...         print(a, end=' ')
...         a, b = b, a+b
...     print()
...
>>> # Now call the function we just defined:
... fib(2000)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597

 

Bytes and Bytearray Operations

str.startswith

line.startswith('#')
回傳 true,如果line的開頭不為 '#'

 
str.strip
line.strip()
刪掉括號內的char (此處為空白字元),回傳字串

line.strip(az.)
刪掉括號內的char(a和z和.和空白),回傳字串

 
str.split
'1,2,3'.split(',')
按照指定的符號進行拆分,回傳 ['1', '2', '3']
'1,2,3'.split(',') [-1]
按照指定的符號進行拆分,回傳索引值[-1]的內容:1

 

Handling Exceptions

def validatePort( port ):
    ''' Validate the given port number
    '''
    try:
        p = int( port )
    except:
        raise Exception( 'Invalid port number: %s' % port )
  • 首先,執行 try clause (在關鍵字 try 和 except 之間的 statements)
  • 如果沒有 exception 發生,except clause 會被跳離,try statement 執行完成
  • 一旦 exception 發生,剩餘的 try clause 將會被跳離,如果match 下面的 except type,則執行底下的except clause
  • If an exception occurs which does not match the exception named in the except clause, it is passed on to outer try statements; if no handler is found, it is an unhandled exception and execution stops with a message as shown above.

 

for arg in sys.argv[1:]:
    try:
        f = open(arg, 'r')
    except IOError:
        print('cannot open', arg)
    else:
        print(arg, 'has', len(f.readlines()), 'lines')
        f.close()

新增 else clause,將一些 statement 從 try clause 放進去
避免當意外發生時,無法執行完剩下必須要執行的 statment (關檔之類的)

 

Methods of File Objects

較簡潔的寫法 with as

with open( '/etc/hosts', 'w' ) as f:
    for line in self.lines:
    f.write(line)

 

Decorator

有人舉了個非常簡單的例子,以下是準備好的 function,可以幫忙在每次呼叫前寫出被呼叫函式名字的 log。

def logged(func): 
    def with_logging(*args, **kwargs): 
        print func.__name__ + " was called" 
        return func(*args, **kwargs) 
    return with_logging

當在自己寫的程式裡,想要在呼叫前寫下名字,就只要在函式前加上 @logged。
@logged 
def f(x): 
   """does some math""" 
   return x + x * x

print f(3)
>>> 
f was called 
12 
>>>

上面那一組程式,等於下面這一句。
def f(x): 
   """does some math""" 
   return x + x * x
f = logged(f)
print f(3)

 
再看其他例子
def makebold(fn): 
    def wrapped(): 
        return "<b>" + fn() + "</b>" 
    return wrapped
def makeitalic(fn): 
    def wrapped(): 
        return "<i>" + fn() + "</i>" 
    return wrapped
@makeitalic 
@makebold 
def hello(): 
    return "hello world"
print hello()
>>> 
<i><b>hello world</b></i> 
>>>

你會發現,為了要使用 decorator 這種語法,所有的操作都是在函式上面。
尤其是裝飾函式,傳入值跟傳出值都是函式。
同時從這個例子裡可以看到,包裏的順序是從下往上,先外包好 <b>,再外包好 <i>。
 
再看一個例子
class entryExit(object):
    def __init__(self, f): 
        print 'entry init enter' 
        self.f = f 
        print 'entry init exit'
    def __call__(self, *args): 
        print "Entering", self.f.__name__ 
        r = self.f(*args) 
        print "Exited", self.f.__name__ 
        return r
print 'decorator using'
@entryExit 
def hello(a): 
    print 'inside hello' 
    return "hello world " + a
print 'test start' 
print hello('friends')
>>> ============ RESTART ============ 
>>> 
decorator using 
entry init enter 
entry init exit 
test start 
Entering hello 
inside hello 
Exited hello 
hello world friends

 

python互動模式

TODO: initial_setup

/usr/lib/python2.7/site-packages/initial_setup/gui/hubs/initial_setup_hub.py
/usr/share/firstboot/modules/cake_initialize.py

  • 確保cake_initialize.py可以被import執行
  • 再到initial_setup_hub.py _on_continue_clicked裡面加入cake_initialize.py (定義continue bottom按下之後發的事)
  • 確保每個module執行正確

 

Note:
cake_initialize.py
103 runcmd('/sbin/service starterd init')
是造成執行緩慢的原因。

更近一步來看,
/etc/init.d/starterd
58 cake_init.sh init 乃是主因。

 

 
到你想要的那一層執行,方便import同一層的modules

python

 
舉例,import某個咚咚順便給他個別名
import cake_initialize as foo

有錯誤的話可能裡面東西有少再check check
 
使用內建函數 dir() 來看所有參數 (parameter) object 的屬性及方法名稱的串列
dir(foo)

The built-in function dir() is used to find out which names a module defines.
It returns a sorted list of strings

 
create a new instance from a class object

b = foo.moduleClass()

 
猜想這個class內的function執行順序,依序執行(測試其流程是否可正常運作)
b.createScreen()
b.apply()

 
最後測試被呼叫到的其他function有無正確執行(看那個function內被assign的變數有無內容)
# something like that
b.configData

 
注意,若是有更改code,要重新reload才會重新讀取
reload(foo)
 
# do these again
b = foo.moduleClass()
b.createScreen()
b.apply()
...

 
 

import os

os.environ
os.environ

取得所有os環境變數, 一大串pair
output: {'LANG': 'en_US.UTF-8', 'TERM': 'xterm-color', …}

os.environ.get
os.environ.get('LANG')

output: 'en_US.UTF-8'

os.path.join
os.path.join('a', 'b', 'c' )

處理檔案或目錄的路徑問題
output: 'a/b/c'

os.makedirs
os.makedirs('/var/log/vinfra/starter')

如同`mkdir -p /var/log/vinfra/starter`

          


 
 
         


 

cheat sheet

python_cheatsheet.png
 
 

hello word


 

dictionary (字典)


 

Note

True 為邏輯上的真, False 為邏輯上的假, None 則是表示虛無,也就是什麼都沒有。
 
Python 內建的資料型態有整數、浮點數、字串、串列、序對、字典等。
[] list,可變
() tuple, 不可變
{} dictionary, key:value所組成, key通常不可變, value沒有限制

# 建立具有五個元素的串列
b = [1, 2.0, "3", [4], (5)]
# 建立具有五個元素的序對
b = (1, 2.0, "3", [4], (5))
# 建立兩個item的字典
b = {1:2.0, "3":[4]}

 

Thread

from threading import Thread
 
class MyThread(Thread):
    def __init__(self, val):
        ''' Constructor. '''
 
        Thread.__init__(self)
        self.val = val
 
    def run(self):
        for i in range(1, self.val):
            print('Value %d in thread %s' % (i, self.getName()))
 
            # Sleep for random time between 1 ~ 3 second
            secondsToSleep = randint(1, 5)
            print('%s sleeping fo %d seconds...' % (self.getName(), secondsToSleep))
            time.sleep(secondsToSleep)

 

Pyro

Pyro的全稱是“ Python Remote Objects”。按照字面即可理解Pyro的功能:提供遠程物件。
Pyro 為Python語言提供異常簡潔的RPC(remote procedure call) 解決方案。其實Python語言中不乏一些更加通用的遠程調用方案,例如都是基於XML的XMLRPC和SOAP。那麼Pyro這樣的單純的Python遠程調用方案具有什麼樣的優勢呢?那就是性能與易用性。
由於動態語言具有強大反射能力,因此實現對象序列化對於Python來說簡直易如反掌。對象的序列化在Python中被稱為pickle,這是許多 Python應用的核心機制。Pyro也正是充分利用pickle的威力,在網絡間提供遠程對象的調用。它的性能要遠遠超過使用XML對遠程對象進行編碼/解碼。同時,它在接口調用設計上也非常簡潔。在服務器端和客戶端只需2、3行代碼就完成對象的封裝與調用,遠比SOAP來得簡單輕鬆。
 

去除空白、換行符號、縮排符號

data = 'node\n'

out = "".join(data.split())

print out 
# 'node'

 

_ _slots_ _ & _ _metaclass_ _ & _ _iter_ _

詳見:datamodel
 

__slots__ = ('_instance', )
用__metaclass__來建立物件
然後iterator就要用def __iter__

lambda

Python提供了一個簡易的function define:lambda,用完即丟,不著痕跡。
讓你實作出很簡單的function(只處理一個運算式)。
 

lambda param1, param2, ... : expression

# 其實就等於

def fun(param1, param2, ...):
    return expression

 
其中的expression不能放assignment,也就是這一行指令不能放=等號。
因為,它就這麼簡單,別把它搞複雜化嘛~
 
def func(x, y, z):
    return x + y + z
#>>>  func(1, 2, 3)
#>>>  6

func2 = lambda x,y,z : x+y+z
#>>>  func2(1, 2, 3)
#>>> 6

# 也可以應用在map上
my_list = [1, 2, 3]
map( lambda i: i*i, my_list)
#>>>  (1, 4, 9)

 

import re

詳見: https://docs.python.org/2/library/re.html
 
刪去多個空白時好用

line = '   hello i      am  ricky'
print re.findall(r'[a-zA-Z0-9_]+', line)
>>> ['hello', 'i', 'am', 'ricky']

[a-zA-Z0-9_] 等同於 \w

 

re.split(r'\s+', line)
除非特別註明,本頁內容採用以下授權方式: Creative Commons Attribution-ShareAlike 3.0 License