Python基礎

基于Python2.7學習

(一)概述

一、為什么學Python

  1. 語法簡單,易上手;
  2. 豐富的庫支持,對Json支持,http、ftp、file、進程等;
  3. 完整的生態圈,一切皆有可能(大數據,云計算,自動化運維等常見);

結合unix-shell和C的使用習慣,在2000年發布2.0實現垃圾回收和Unicode支持。

二、特點

  • 免費開源
  • 動態數據類型,高層語言(沒有類型檢查)
  • 可移植行,個別模塊跟操作系統os有關
  • 面向對象
  • 可擴展性,底層用C實現
  • 豐富的標準庫

三、生態圈

  • 不同解釋器支持
  • web應用開發
  • 科學計算與大數據分析
  • 云計算

幾種解釋器:

  • Cpython解釋器:C語言實現,常見解釋器;
  • Jython解釋器:JVM,Java庫;
  • IronPython:.NET
  • pypy:基于JIT的python解釋器,即時編譯;

四、Python web開發框架

  • Django,最流行和成熟的web開發框架
  • Tornado,Facebook開發的高性能web服務
  • Uliueb,國人開發的web框架
  • Flask

五、Python社區
華蟒用戶組,中文社區
啄木鳥社區
豆瓣Python小組

六、安裝Django

pip install django --index-url=http://pypi.douban.com/simple
python manage.py install

(二)Python基礎

一、Python參數傳遞
參數傳遞順序依次:

  • 位置參數傳遞
  • 關鍵字傳遞
  • 表傳遞(列表)
  • 字典傳遞

位置參數傳遞:值傳遞;
關鍵字傳遞:根據每個參數的名字傳遞;
表傳遞:表傳遞給函數的是一個指針,指針指向序列在內存中的位置;
字典傳遞:包裹傳參;

例如:

def f(a, b=None, c=3, *args, **kwargs):
    pass

混合傳參順序:先位置,再關鍵字,再包裹位置,再包裹關鍵字;
關鍵字傳參與位置傳參混用時,位置傳參須在關鍵字傳參之前;

def foo(name, count=1, *args, **kwargs):
    print name
    print count
    print args
    print kwargs
foo("python", 12, *(13,14,15), **{'a':1, 'b':2})
foo("python", *(13,14,15), **{'a':1, 'b':2})

二、MVT架構

MVT架構

三、Django框架

  1. 包管理器安裝
pip install django --index-url http://pypi.douban.com/simple

倉庫:

http://pypi.douban.com/simple  # 豆瓣python模塊鏡像
http://pypi.python.org/pypi    # 中央倉庫
  1. 從源碼安裝
    下載Django的壓縮包并解壓;然后執行:
python setup.py install
  1. 創建第一個Django的project
django-admin.py startproject [projname]

項目目錄結構:

manage.py  # Django應用的管理工具
project/
    settings.py  # 整個項目的核心配置文件,數據庫、緩存、session等
    urls.py  # URL轉發的配置文件
    wsgi.py

manage.py:管理Django項目命令行工具,支持多個命令,支持擴展自定義的命令,創建數據庫schema,啟動內嵌的應用服務器;

python manage.py [subcomand]
python manage.py help

settings.py:整個項目的核心配置文件

  • 數據庫的連接信息
  • 緩存配置
  • session配置
  • 靜態文件配置,比如:css、js
  • 用戶自定義信息

運行app:

python manage.py startapp [app name]
  1. ORM
  • Django原生支持關系映射;
  • 每個APP的models.py里面包含了schema的信息;
  • 每次啟動項目的時候,都會去驗證models.py中的schema和數據庫中表對應結構的一致性;
  • 通過python manage.py syncdb來創建表;

model類:
每個model類表示一張表,生成的數據庫表的名字默認是APP的名字_類的名字
每個model類里面都有多個Filed的Instance變量;

primary key:
默認情況下每個Model類,Django都會自動添加一個id的Integer Field變量作為主鍵;
用戶也可以自己指定pk字段,默認就可以;

Query:

[Model Class].Objects.get()
eg. Blog.Objects.get(pk=1)
[Model Class].Objects.[filter/exclude] # 根據特定條件篩選記錄
[Model Class].Objects.all()  # 返回表中的全部數據

QuerySet:
Filter/exclude/all :三個API返回都是一個QuerySet的對象;
QuerySet :可以理解為Model實例的集合;
Lazy Mode :真正Query時查詢,不是時時查詢;

QuerySet in Chain :

Blog.Objects.all().filter(count_it=10)

ORM缺陷:
需要先手工創建一個空的數據庫,無法更新schema的變量;第三方解決http://south.aeracode.org/,自Django1.7+,migration被構建到Django核心模塊中,可以使用migration工具遷移schema,更新數據庫。

  1. URL與視圖的映射
  • 無參數的映射
url(r'^test/$', get_blog_view)
  • 帶位置參數的映射
url(r'^(\d{4})/$', get_blog_view)
def get_blog_view(req, bid):
    pass
  • 關鍵字參數的映射
url(r'^(?P<blog id>\d{4})/$', get_blog_view)
def get_blog_view(req, blogid):
    pass

URL采用最先匹配原則,匹配范圍大的URL放在最后。

  1. Template
    {...} 變量
    {% ... %} 模板標簽
    {% IF %} ... {% END IF %}
    {% FOR %} ... {% END FOR %}

模板上下文:
視圖函數返回一個模板的時候,需要傳入一個上下文(Context),Context是一個字典,key表示的是模板中的變量名字,value表示渲染完成后實際展示在HTML中的內容。

def ament_datetime(request):
    now = datetime.datetime.now()
    return render_to_response('current_datetime.html', {'current_date': now})

模板繼承:
css、HEADER、FOOTER寫一次,其他模塊可用
通過Block ... Extend繼承

靜態文件處理:
JS、CSS等靜態文件的請求處理,settings.py中的STATIC變量指定了靜態文件的根目錄。

四、Python語法

  1. 編寫腳本文件在第一行添加代碼
#!/usr/bin/python
#!/usr/local/bin/python

在第二行添加:

# coding:utf8
#-*- coding:utf8 -*-
  1. 鏈式賦值:
a, b = "django", 2

python不支持A++,A--操作;
Python3:只支持長整型;
切片操作:slice
布爾值:True ,False
dict[key] 查找,效率為O(1)
字典中key唯一,可以Hash的值。
dict[key]查找,也可以用key in dict方式來判斷字典是否包含key的鍵。

  1. 循環語句
for ... :
  ...
else:
  ...

當for, while正常循環退出時,會執行else語句;當for, while非正常退出時,不會執行else語句;
非正常退出,相當于break

try ... :
  ...
except _, e:
  ...
except e2:
  ...
else:
  ...
finally:
  ...

不拋異常時,執行else語句

  1. Python多重繼承
Class A(ParentA, ParentB, ...):
    pass

__init__是Class構造函數,用來初始化對象

isDuplicate(s)  # s是一個字符串,是否含有重復的字符
isPalindrome(s)  # s是一個字符串,字符串是否是回文
  1. 搜索路徑
    Python會在以下路徑中搜索他想要的尋找的模塊:
  • 程序所在文件夾
  • 標準庫的安裝路徑
  • 操作系統環境變量PYTHONPATH所包含的路徑
  1. Python解釋器負責內存管理
    id():返回對象的內存地址
    引用計數為0時,GC才回收內存
    整型緩沖池:整型數據被放到一個緩沖池中
a=1
b=1

id(a)與id(b)一樣,用來判斷是否為同一對象。
is:用來判斷兩個變量是不是指向同一個內存對象
python緩存整數和短字符串,因此每個對象只存有一份,所有整數的引用都指向同一個對象。即使使用賦值語句,也只是創造了新的引用,而不是對象本身。

  1. 包管理器
    pip是Python自帶的包管理程序
pip install web.py
pip uninstall web.py
pip install --upgrade web.py
which python  # 查看Python安裝路徑
whereis python # 查看Python安裝路徑
pip install --install-option="--prefix=/home/vamei/util/" web.py  # 模塊安裝路徑:/home/vamei/util/
  1. global
def func1():
    global i
    global lock
if __name__ == "__main__":
    i = 100
    lock = threading.Lock()
    func1()

在函數中使用global聲明全局變量;i、lock為不可變數據對象,被當作一個局部變量,所以用global聲明;
對于可變數據對象,則不需要global聲明;可以將可變數據對象作為參數來傳遞給線程函數,這些線程將共享這些可變數據對象。

  1. 線程
    在UNIX平臺上,當某個進程終結之后,該進程需要被其父進程調用wait,否則進程成為僵尸進程(Zombie),所以有必要對每個process對象調用join()方法(實際上等同于wait)。對于多線程來說,由于只有一個進程,所以不存在此必要性。
    多線程,可以使用共享資源,比如使用全局變量或傳遞參數。
    多進程應避免共享資源,每個進程有自己獨立的內存空間,可以通過共享內存和Manager的方法共享資源。
  2. 列表解析
    列表解析比for循環性能好很多
[expr for iter in iterable [if condition]]   # 列表解析

filter(function, iter):用來對列表中的元素進行過濾,function返回false時,該元素就被丟棄。
map(function, iter):把function(x)作用于列表的每一個元素,然后函數的結果根據順序構成一個新的列表返回。

列表解析缺點:
內存使用效率較低,每次都要把被操作的列表中的元素一次性裝載到內存里。
另一個解決方案:生成器表達式

  • 每次只加載一個元素到內存中
  • 返回一個可迭代的對象
  1. 生成器表達式
(expr for iter in iterable [if condition])  # 返回generator對象
res = (expr for iter in iteralbe [if condition])
for i in res:
    print i

對內存要求較高時,使用生成器表達式
返回范圍較大的列表時用xrange

  1. 字典和集合
    字典:任何一個可以被Hash的數據類型都可以用作key;字典是無序的,值可以是任意數據類型;基于Hash表實現。
    類實例做key,需要類實現__hash__方法返回哈希值。
    列表不可以做key,字典本身不能做key
    元組可以做key,但要求元組中不包含列表、字典等可變類型的數據結構。
    使用hash()函數來檢查是否可以用作key
    字符串可以做key
d = {'a':1, 'b':2}
d = dict(a=1, b=2)
d.get('c', 'Default')  # 若字典中沒有key為c,則返回默認值Default
d.keys()  # 返回已存在的key的可迭代對象
if 'a' in d:
  print e.get('a')    # 使用in判斷key是否在字典中

集合:元素不可重復,一組無序排列的可哈希的值,支持Union、intersection等。
set:可變集合,值是可哈希的
frozenset:不可變集合
in:判斷是否存在,for:遍歷
集合操作函數:
更新集合:add、remove、update
高級操作:

  • union:聯合(|)
  • intersection:交集(&)
  • difference:差集(-)
  • symmetric_difference:異或(^)

五、函數式編程

  1. 函數對象
def foo():
    pass

foo:函數對象
foo():函數調用

a = foo
a()  # 等價函數調用foo()

不支持重載,在同一模塊中定義相同名字的函數,無論參數個數,后定義的一個會覆蓋之前的那個。
可以返回多個值,以元組形式返回,也可以用多個變量接收返回的多個值。

  1. lambda
    返回可調用的函數對象
    不需要return來返回結果
    函數聲明和定義均在一行
foo = lambda x : x+1 if x > 10 else x - 10
foo(1)
  1. 變量查找順序
  • 局部作用域
  • 全局作用域
  • global關鍵字
  1. 閉包
def fx(x):
    def gy(y):
        return x + y
    return gy
foo = fx(5)
print foo(10)    # 結果15

裝飾器:被用于有切面需求的場景,較為經典的有插入日志、性能測試、事務處理、Web權限校驗、Cache等。

  • 無參數decorator
    生成一個新的裝飾器函數
  • 有參decorator
    有參裝飾,裝飾函數先處理參數,再生成一個新的裝飾器函數,然后對函數進行裝飾。
  1. 面向對象編程
    特征:
  • 抽象/實現
  • 封裝/接口
  • 合成
  • 派生/繼承
  • 多態
  • 自省/反射
class A():    # 經典類
    pass
class B(object):  # 新式類
    pass

建議使用新式類,新式類必須有一個父類;
可使用type()測試,type(A)和type(B)
type(A):返回<type 'classobj'>
type(B):返回<type 'type'>
調用父類的__init__方法:

A.__init__(self)  # 經典類
super(B, self).__init__()

實例方法:
方法定義在類中,第一個位置參數為self,self表示實例對象的本省,只能被實例所調用;在調用實例方法時,不需顯示地傳入self,解釋器默認傳入。
Python構造函數:__init__,但不是真正的構造函數,不會創建對象。
使用__new__來構造對象
使用__init__來初始化對象
當使用A()創建實例時,默認使用__init__方法初始化對象。
類變量和實例變量:
類變量綁定在類上,實例共享;實例變量綁定在實例對象上,通常使用self.x來表示實例變量。給實例對象賦值時,默認創建實例變量;在查找時,先查找對象本身的屬性實例變量,再查找類的屬性類變量。

class A(object):
    author = "Guido"
    def __init__(self, page):
        self.page = page
book_a = A(10)
book_b = A(100)
book_a.author = "python"
print book_a.author    # 輸出"python",author作為book_a的實例變量
print book_b.author    # 輸出"Guido",沒有賦值,使用類變量,可用id()檢查
  1. 類方法和靜態方法
    類方法的第一個位置參數不是self,而是cls,表示綁定到類上。
    使用@staticmethod來裝飾一個靜態方法,靜態方法不需要self和cls。
    使用@classmethod來裝飾一個類函數。

類方法:

@classmethod
def class_method(cls):
    pass

靜態方法:

@staticmethod
def static_method(msg):
    print "[" + msg + "]"

子類若沒有自己定義__init__方法,會默認調用基類的__init__方法;
若子類定義了__init__方法,則需要顯式調用基類的__init__方法,并且傳入self參數;
super():只工作在新式類
dir() :查看對象所有屬性和方法
__dict__:類的字典屬性
__doc__:類的文檔屬性
__new__:類函數,構造對象
__init__:初始化對象
__del__:當對象的引用計數為0時,自動調用,釋放內存,要首先調用基類的__del__
__X:定義private變量,只有類的內部可以引用
對于實例對象不存在的屬性進行賦值,會動態創建這個屬性,新式類可以通過設定__slot__的類屬性來防止這個問題。

issubclass(sub, sup)  # 判斷是否為子類
isinstance(obj, classType)  # 判斷是否為類的實例

super(A, self) 返回Instance
super(A, cls) 返回type

  1. 單元測試
  • nose
  • pytest
    namespace:相當于字典
    模塊中的變量相當于單例模式
    hashcod要求唯一,計算下標
  1. Python單例模式
class A(object):
    instance = None
    def __new__(cls, *args, **kwargs):
        if not cls.instance:
            cls.instance = object.__new__(cls, *args, **kwargs)
            return cls.instance
print id(A())
print id(A())    # 值相同
  1. python常用模塊
    模塊文檔API:
    https://docs.python.org/2/library/
    使用場景:
  • 操作系統相關
  • 文件路徑處理
  • 網絡處理
  • 數據處理
    os.path模塊:處理文件路徑
os.path.join("/a", "b", "c", "d.txt")
__file__  # 獲取當前文件/模塊的路徑

os模塊:

  • 系統環境變量
  • Linux系統上的文件處理
  • 進程處理

os.environ:可以改環境變量
sys:獲取傳入給程序的外部參數argv,進程的輸入輸出流sys.stdout,sys.stdin環境信息相關。

import sys
sys.executable    #判斷程序運行的環境

Python從外部獲取的參數為字符串。

# 重定向stdout
_back = sys.stdout
f = open("txt.txt", "w")
sys.stdout = f
print "kkk"
f.close()

sys.platform:查看程序運行在什么平臺
subprocess:

      Popen:用來創建子進程

網絡相關:

  • urllib
  • httplib

數據處理:

  • xml模塊
  • json模塊

六、virtualenv和virtualenvwrapper

  1. virtualenv
pip install virtualenv
pip freeze
pip freeze | wc -l   # 統計安裝的模塊
virtualenv ENV    # 創建一個virtualenv的一個虛擬環境ENV
source ./ENV/bin/activate  # 啟動ENV
deactivate    # 離開virtualenv環境
which python    # 查看Python可執行文件的路徑

所有安裝在系統范圍內的包對于virtualenv是可見的,這意味著若將simplejson安裝在系統Python目錄中,它會自動提供給所有的virtualenv使用。這種行為可以被更改,在創建virtualenv時增加--no-site-packages選項的virtualenv就不會讀取系統包,例如:virtualenv ENV --no-site-package

  1. virtualenvwrapper

建立在virtualenv上的工具,通過它可以方便的創建/激活/管理/銷毀虛擬環境。

workon ENV    # 啟用ENV
workon       # 列出所有虛擬環境
mkvirtualenv  ENV    # 創建
workon ENV
rmvirtualenv  ENV

七、回顧

  1. 當應用計數為0時,GC回收變量占用的 內存;
    del 變量名:刪除變量,釋放占用的內存;
    is語句:用來判斷兩個變量是不是指向同一個內存對象;
  2. 聲明編碼格式,支持中文
# coding:utf8  或
# -*- coding:utf8 -*-    # 一般放在第二行
#!/usr/bin/python    # 放在第一行
  1. built-in類型
  • 數值類型
  • 布爾類型
  • 序列類型
  • 集合類型
  • 映射類型
  1. python模塊
    Python程序由多個模塊文件組成,模塊是程序執行的唯一入口;模塊是可以被其他模塊導入,模塊文件為文件名。
  • 模塊執行最簡單方法
python [module].py
#! /usr/bin/python      # 當前python解釋器
  • 也可以使用./module.py來調用

模塊中定義了什么:

  • 變量[模塊級別]
  • 函數的定義
  • 類的定義
  • 程序的實際調用邏輯
  1. 數據類型
    使用弱類型
  • built-in類型
  • 自定義的類型(類,integer)

變量名字大小寫敏感,以下劃線、數字、字母命名,以下劃線、字母開頭;
支持多個變量的同時定義,簡化代碼編寫:
a, b = 'django', 2
數據類型:

  • 整型:32/64 bit,在python3已移除
  • 長整型:沒有長度限制,受內存大小限制
  • 浮點型
  • 復數類型
/  # 普通除法,兩個均為整數時,四舍五入;為浮點數時,結果為浮點數;
//  # 地板除,只保留整數部分

空列表、空元組、空字符串、0均表示False

對象三要素:

  • identity(身份),對應于內存地址,不可修改
  • type(類型),不可修改
  • value(值),immutable不可修改和mutable可修改

list | tuple | string正負下標表示:

  • 正:0,1,2,...,n-1
  • 負:-n,-n-1,...,-2,-1

list支持extend操作,支持原地修改
[list].extend([list])
list(), tuple():創建了一個新的序列對象
字符串是不可變序列,任何一點修改都會創建新的字符串對象。每次'+'操作都會生成一個新的字符串對象。
"".join(序列)
拷貝:

  • 淺拷貝:list,tuple工廠函數;切片;copy模塊的copy函數;
    淺拷貝不會生成一個新的 序列,指向同一個列表。
  • 深拷貝:生成一個新的序列
import copy
c = copy.deepcopy(a)

Tips:持續更新。。。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容