Python
Function,Module,Class,Package Note
Reference
https://docs.python.org/3/tutorial/modules.html
http://openhome.cc/Gossip/Python/Class.html
Function
function
可以用兩種方式來表示def,
lambda
def
max(a, b):
return
a
if
a
> b else
b
|
lambda
a, b: a if
a
< b else
b
|
這樣的函式稱為 λ
函式或是匿名函式(Anonymous
function),當然,你可以將函式指定給變數:
min
= lambda a, b: a if
a
< b else
b
minimum
= min
min(10,
20) # 傳回 10
|
Module
在
Python
中,模組是幾個重要抽象層的機制之一,也許是最自然的機制之一,只要你建立了一個原始碼檔案
modu.py,你就建立了一個模組 modu
,原始碼主檔名就是模組名稱。
import
modu
陳述句會在相同目錄下尋找
modu.py,如果沒找到,則會試著尋找在 sys.path
中遞迴地尋找
modu.py,如果還是沒有,則會引發 ImportError
例外。
模組提供了名稱空間。模組中的變數、函式與類別,基本上需透過模組的名稱空間來取得。在
Python
中,import
、import
as
與 from
import
是陳述句
from
modu import max, min # import這兩個函式
from
modu import * #
import全部函式
或是可以使用modulename.functionname來呼叫在別的module中的function
,ex: modu.max
Note
可以利用imp.reload()來自動載入更新過的檔案
For
efficiency reasons, each module is only imported once per
interpreter session. Therefore, if you change your modules, you
must restart the interpreter – or, if it’s just one module
you
want to test interactively, use imp.reload(),
e.g.import imp; imp.reload(modulename).
|
_name__
每一個module裡面都會有個__name__的全域變數,指向module的名稱
Within
a module, the module’s name (as a string) is available as the value
of the global variable __name__.
if __name__ == "__main__"
這表示如果直接執行python檔案,__name__會指向__main__,但是如果是從別的file
import這個python檔案,__name__會指向module的名稱
When
the Python interpreter reads a source file, it executes all of the
code found in it. Before executing the code, it will define a few
special variables. For example, if the python interpreter is running
that module (the source file) as the main program, it sets the
special __name__
variable
to have a value "__main__"
.
If this file is being imported from another module, __name__
will
be set to the module's name.
using_name.py
#!/usr/bin/python
# Filename:
using_name.py
if __name__
== '__main__':
print
'This program is being run by itself'
else:
print 'I
am being imported from another module'
|
>>>
========================= RESTART ================================
>>>
This
program is being run by itself
>>>
import using_name
I am being
imported from another module
>>>
using_name.__name__
'using_name'
>>>
|
Class
Gossip@openhome裡面寫的一個範例
class Account:
def __init__(self, number, name):
self.number = number
self.name = name
self.balance = 0
def deposit(self, amount):
if amount <= 0:
raise ValueError('must be positive')
self.balance += amount
def withdraw(self, amount):
if amount <= self.balance:
self.balance -= amount
else:
raise RuntimeError('balance not enough')
|
每個函數def都需要一個self做為指標,就像c++裡面的this一樣,number與name是這個class對外的變數,blance則是內部的變數
>>>
acct = Account('123456', 'mary')
>>>
acct.number
'123456'
>>>
acct.name
'mary'
>>>
acct.deposit(100)
>>>
acct.balance
100
>>>
acct.withdraw(50)
>>>
acct.balance
50
|
Package
假設現在你有一些
.py
檔案,別人同樣也有一堆
.py
檔案,你們的檔案現在得放在同一專案中,那麼檔案名稱衝突是有可能發生的,最好是為你們的
.py
檔案分別開設目錄。使用
Python
時,你可以在開設的目錄中放個 __init__.py 檔案,這樣
Python
就會將這個目錄視為一個套件,而目錄名稱就是套件名稱。
使用 import
pack.modu
陳述時,Python
會尋找
pack
目錄,看看裏頭是否有
__init__.py
檔案,然後看看目錄中是否有個
modu.py
檔案。__init__.py
檔案空白也無所謂,實際上當中也可以寫些程式碼,用來執行這個套件中都會需要的初始工作,不過慣例上,除非你有真正不得已的理由,請保持
__init__.py
檔案空白。在找到模組後,實際上會執行其中頂層範疇中的程式碼,之後,模組中的變數、函式、類別等名稱,可以透過 pack.modu
來取得。
引入參數的階層是
package.module
如果階層較長(多層次的套件),可以用import
as
sound/ Top-level package
__init__.py Initialize the sound package
formats/ Subpackage for file format conversions
__init__.py
wavread.py
wavwrite.py
aiffread.py
aiffwrite.py
auread.py
auwrite.py
...
effects/ Subpackage for sound effects
__init__.py
echo.py
surround.py
reverse.py
...
filters/ Subpackage for filters
__init__.py
equalizer.py
vocoder.py
karaoke.py
...
|
import sound.effects.echo
sound.effects.echo.echofilter(input, output, delay=0.7, atten=4)
from sound.effects import echo
echo.echofilter(input, output, delay=0.7, atten=4)
from sound.effects.echo import echofilter
echofilter(input, output, delay=0.7, atten=4)