代碼不會正常運行,拋出 TypeError 異常。javascript
# 好比修改元祖。會報錯 TypeError: 'tuple' object does not support item assignment
print 方法默認調用 sys.stdout.write 方法,即往控制檯打印字符串。html
import sys obj = "hello world!" print(obj) # print等同於 sys.stdout.write(obj + '\n')
class Parent(object): x = 1 class Child1(Parent): pass class Child2(Parent): pass # 繼承指向父類x所在地址:1635999904 print(id(Parent.x), id(Child1.x), id(Child2.x)) # 1 1 1 print(Parent.x, Child1.x, Child2.x) Child1.x = 2 # 1 2 1 print(Parent.x, Child1.x, Child2.x) Parent.x = 3 # 3 2 3 print(Parent.x, Child1.x, Child2.x)
在 Python3 中,input()獲取用戶輸入,不論用戶輸入的是什麼,獲取到的都是字符串類型的。前端
在 Python2 中,input()獲取用戶輸入,不論用戶輸入的是什麼,獲取到的就是什麼數據類型的。java
詳情見:http://www.javashuo.com/article/p-nlwwkbku-by.htmlpython
range返回一個列表,直接開闢一塊內存空間保存列表
xrange返回一個生成器,邊循環邊使用,只有在使用時纔會開闢空間
"""方法1:經過生成器屢次讀取""" # 生成器 def get_lines(): with open('Cookie和Session.py', 'r', encoding='utf-8') as f: while True: data = f.readlines(100) if data: yield data else: break # 迭代器 file = get_lines() print(next(file)) print(next(file)) print(next(file))
方法2:使用linux命令切割文件,分屢次進行讀取mysql
"""能夠經過linux命令split切割成小文件,而後再對數據進行處理,此方法效率比較高。能夠按照行數切割,能夠按照文件大小切割""" python@ubuntu:~/Desktop$ split -l 2 requirements.txt re.txt 意思:按照兩行切割requirements.txt文件,切割後的文件名叫re.txt。 回車後會生成好多re文件,裏面都是兩行代碼
http://www.javashuo.com/article/p-pebfbare-cg.htmllinux
os 操做系統,time 時間,random 隨機,pymysql 鏈接數據庫,threading 線程,multiprocessing
進程,queue 隊列。
第三方庫:
django 和 flask 也是第三方庫,requests,virtualenv,selenium,scrapy,xadmin,celery,
re,hashlib,md5。
經常使用的科學計算庫(如 Numpy,Scipy,Pandas)。c++
init 在對象建立後,對對象進行初始化。
new 是在對象建立以前建立一個對象,並將該對象返回給 init。web
__new__: 對象的建立,是一個靜態方法,第一個參數是cls。(想一想也是,不多是self,對象還沒建立,哪來的self)ajax
其必需要有返回值,返回實例化出來的實例,須要注意的是,能夠return父類__new__()出來的實例,也能夠直接將object的__new__()出來的實例返回。
class Bar(object): pass class Foo(object): def __new__(cls, *args, **kwargs): return Bar() print(Foo())
# 今年的第幾天 import datetime year = int(input("請輸入年份:")) month = int(input("請輸入月份:")) day = int(input("請輸入天數:")) data1 = datetime.date(year=year, month=month, day=day) data2 = datetime.date(year=year, month=1, day=1) result = data1 - data2 # <class 'datetime.timedelta'> 1 day, 0:00:00 result = result.days + 1 print(result)
import random a = [1, 2, 3, 4] # 返回值爲None random.shuffle(a) print(a)
os.remove()刪除文件
os.rename()重命名文件
os.walk()生成目錄樹下的全部文件名
os.chdir()改變目錄
os.mkdir/makedirs 建立目錄/多層目錄
os.rmdir/removedirs 刪除目錄/多層目錄
os.listdir()列出指定目錄的文件
os.getcwd()取得當前工做目錄
os.chmod()改變目錄權限
os.path.basename()去掉目錄路徑,返回文件名
os.path.dirname()去掉文件名,返回目錄路徑
os.path.join()將分離的各部分組合成一個路徑名
os.path.split()返回(dirname(),basename())元組
os.path.splitext()(返回 filename,extension)元組
os.path.getatime\ctime\mtime 分別返回最近訪問、建立、修改時間
os.path.getsize()返回文件大小
os.path.exists()是否存在
os.path.isabs()是否爲絕對路徑
os.path.isdir()是否爲目錄
os.path.isfile()是否爲文件
sys.exit(n) 退出程序,正常退出時 exit(0)
sys.hexversion 獲取 Python 解釋程序的版本值,16 進制格式如:0x020403F0
sys.version 獲取 Python 解釋程序的版本信息
sys.maxint 最大的 Int 值
sys.maxunicode 最大的 Unicode 值
sys.modules 返回系統導入的模塊字段,key 是模塊名,value 是模塊
sys.path 返回模塊的搜索路徑,初始化時使用 PYTHONPATH 環境變量的值
sys.platform 返回操做系統平臺名稱
sys.stdout 標準輸出
sys.stdin 標準輸入
sys.stderr 錯誤輸出
sys.exc_clear() 用來清除當前線程所出現的當前的或最近的錯誤信息
sys.exec_prefix 返回平臺獨立的 python 文件安裝的位置
sys.byteorder 本地字節規則的指示器,big-endian 平臺的值是'big',little-endian 平臺的值是'little'
sys.copyright 記錄 python 版權相關的東西
sys.api_version 解釋器的 C 的 API 版本
sys.version_info 元組則提供一個更簡單的方法來使你的程序具有 Python 版本要求功能
一、使用多進程,充分利用機器的多核性能
二、對於性能影響較大的部分代碼,可使用 C 或 C++編寫
三、對於 IO 阻塞形成的性能影響,可使用 IO 多路複用來解決
四、儘可能使用 Python 的內建函數
五、儘可能使用局部變量
pwd 顯示工做路徑
ls 查看目錄中的文件
cd /home 進入 '/ home' 目錄'
cd .. 返回上一級目錄
cd ../.. 返回上兩級目錄
mkdir dir1 建立一個叫作 'dir1' 的目錄'
rm -f file1 刪除一個叫作 'file1' 的文件',-f 參數,忽略不存在的文件,從不給出提示。
rmdir dir1 刪除一個叫作 'dir1' 的目錄'
groupadd group_name 建立一個新用戶組
groupdel group_name 刪除一個用戶組
tar -cvf archive.tar file1 建立一個非壓縮的 tarball
tar -cvf archive.tar file1 file2 dir1 建立一個包含了 'file1', 'file2' 以及 'dir1'的檔案文件
tar -tf archive.tar 顯示一個包中的內容
tar -xvf archive.tar 釋放一個包
tar -xvf archive.tar -C /tmp 將壓縮包釋放到 /tmp 目錄下
tar -cvfj archive.tar.bz2 dir1 建立一個 bzip2 格式的壓縮包
tar -xvfj archive.tar.bz2 解壓一個 bzip2 格式的壓縮包
tar -cvfz archive.tar.gz dir1 建立一個 gzip 格式的壓縮包
tar -xvfz archive.tar.gz 解壓一個 gzip 格式的壓縮包
d = {'a': 3, 'b': 1, 'c': 2, 'd': 4} # 有返回值 d_reverse = sorted(d.items(), key=lambda x:x[1], reverse=True) d_sorted = sorted(d.items(), key=lambda x:x[1], reverse=False) print(d_reverse,d_sorted)
類方法:是類對象的方法,在定義時須要在上方使用「@classmethod」進行裝飾,形參爲 cls,
表示類對象,類對象和實例對象均可調用;
類實例方法:是類實例化對象的方法,只有實例對象能夠調用,形參爲 self,指代對象自己;
靜態方法:是一個任意函數,在其上方使用「@staticmethod」進行裝飾,能夠用對象直接調用,
靜態方法實際上跟該類沒有太大關係。
內存管理機制:引用計數、垃圾回收、內存池。
引用計數:
引用計數是一種很是高效的內存管理手段, 當一個 Python 對象被引用時其引用計數增長 1, 當
其再也不被一個變量引用時則計數減 1. 當引用計數等於 0 時對象被刪除。
垃圾回收 :
1. 引用計數
引用計數也是一種垃圾收集機制,並且也是一種最直觀,最簡單的垃圾收集技術。當 Python 的某
個對象的引用計數降爲 0 時,說明沒有任何引用指向該對象,該對象就成爲要被回收的垃圾了。好比
某個新建對象,它被分配給某個引用,對象的引用計數變爲 1。若是引用被刪除,對象的引用計數爲 0,
那麼該對象就能夠被垃圾回收。不過若是出現循環引用的話,引用計數機制就再也不起有效的做用了
2. 標記清除
若是兩個對象的引用計數都爲 1,可是僅僅存在他們之間的循環引用,那麼這兩個對象都是須要被
回收的,也就是說,它們的引用計數雖然表現爲非 0,但實際上有效的引用計數爲 0。因此先將循環引
用摘掉,就會得出這兩個對象的有效計數。
3. 分代回收(屢次沒清除的保留,下次不回收這些內容)
從前面「標記-清除」這樣的垃圾收集機制來看,這種垃圾收集機制所帶來的額外操做實際上與系統
中總的內存塊的數量是相關的,當須要回收的內存塊越多時,垃圾檢測帶來的額外操做就越多,而垃圾
回收帶來的額外操做就越少;反之,當需回收的內存塊越少時,垃圾檢測就將比垃圾回收帶來更少的額
外操做。
內存池:
1. Python 的內存機制呈現金字塔形狀,-1,-2 層主要有操做系統進行操做;
2. 第 0 層是 C 中的 malloc,free 等內存分配和釋放函數進行操做;
3. 第 1 層和第 2 層是內存池,有 Python 的接口函數 PyMem_Malloc 函數實現,當對象小於
256K 時有該層直接分配內存;
4. 第 3 層是最上層,也就是咱們對 Python 對象的直接操做;
Python 在運行期間會大量地執行 malloc 和 free 的操做,頻繁地在用戶態和核心態之間進行切
換,這將嚴重影響 Python 的執行效率。爲了加速 Python 的執行效率,Python 引入了一個內存池
機制,用於管理對小塊內存的申請和釋放。
Python 內部默認的小塊內存與大塊內存的分界點定在 256 個字節,當申請的內存小於 256 字節
時,PyObject_Malloc 會在內存池中申請內存;當申請的內存大於 256 字節時,PyObject_Malloc 的
行爲將蛻化爲 malloc 的行爲。固然,經過修改 Python 源代碼,咱們能夠改變這個默認值,從而改
變 Python 的默認內存管理行爲
不可變參數用值傳遞:
像整數和字符串這樣的不可變對象,是經過拷貝進行傳遞的,由於你不管如何都不可能在原處改變
不可變對象
可變參數是引用傳遞的:
好比像列表,字典這樣的對象是經過引用傳遞、和 C 語言裏面的用指針傳遞數組很類似,可變對象
能在函數內部改變。
Python 中一切皆對象,函數名是函數在內存中的空間,也是一個對象。
回調函數是把函數的指針(地址)做爲參數傳遞給另外一個函數,將整個函數看成一個對象,賦值給調
用的函數。
# 單例模式,不管調用多少次,獲得對象的引用相同(內存地址相同) # 思路:沒建立對象就先分配空間,分配好空間每次都返回這個內存空間地址,再也不使用new方法從新分配 class MusicPlayer(object): # 記錄單例對象的引用,第一個被建立的對象 instance = None # 記錄是否執行過初始化動做 init_flag = False def __new__(cls, *args, **kwargs): # 1.判斷類屬性是否爲空對象 if cls.instance is None: # 2.調用父類的方法,爲第一個對象分配空間 cls.instance = super().__new__(cls) # 3.返回保存的對象引用 return cls.instance # 4.改寫初始化方法,使它只執行一次 def __init__(self): # 5.判斷是否執行過初始化動做,爲Ture直接返回 if MusicPlayer.init_flag: return # 6.若是沒有執行就進行初始化 print("初始化") # 7.修改類屬性標記 MusicPlayer.init_flag = True # 建立多個對象,地址相同 player1 = MusicPlayer() player2 = MusicPlayer() print(player1) print(player2)
應用場景:
(1)資源共享的狀況下,避免因爲資源操做時致使的性能或損耗等。如日誌文件,應用配置。(2)控制資源的狀況下,方便資源之間的互相通訊。如線程池等。 1.網站的計數器 2.應用配置 3.多線程池 4.數據庫配置,數據庫鏈接池 5.應用程序的日誌應用....
迭代器是一個更抽象的概念,任何對象,若是它的類有 next 方法和 iter 方法返回本身自己,對於 string、list、
dict、tuple 等這類容器對象,使用 for 循環遍歷是很方便的。在後臺 for 語句對容器對象調用 iter()函數,iter()
是 python 的內置函數。iter()會返回一個定義了 next()方法的迭代器對象,它在容器中逐個訪問容器內元素,next()
也是 python 的內置函數。在沒有後續元素時,next()會拋出一個 StopIteration 異常。
生成器(Generator)是建立迭代器的簡單而強大的工具。它們寫起來就像是正規的函數,只是在須要返回數
據的時候使用 yield 語句。每次 next()被調用時,生成器會返回它脫離的位置(它記憶語句最後一次執行的位置
和全部的數據值)
區別:生成器能作到迭代器能作的全部事,並且由於自動建立了 iter()和 next()方法,生成器顯得特別簡潔,並且
生成器也是高效的,使用生成器表達式取代列表解析能夠同時節省內存。除了建立和保存程序狀態的自動方法,當
發生器終結時,還會自動拋出 StopIteration 異常。
<.*>是貪婪匹配,會從第一個「<」開始匹配,直到最後一個「>」中間全部的字符都會匹配到,中間可能會包含
「<>」。
<.*?>是非貪婪匹配,從第一個「<」開始日後,遇到第一個「>」結束匹配,這中間的字符串都會匹配到,可是
不會有「<>」。
進程:程序運行在操做系統上的一個實例,就稱之爲進程。進程須要相應的系統資源:內存、時間
片、pid。
http://www.javashuo.com/article/p-xwaonjaw-cw.html
http://www.javashuo.com/article/p-hgxrhfiz-dc.html
這個問題被問的機率至關之大,其實多線程,多進程,在實際開發中用到的不多,除非是那些對項
目性能要求特別高的,有的開發工做幾年了,也確實沒用過,你能夠這麼回答,給他扯扯什麼是進程,
線程(cpython 中是僞多線程)的概念就行,實在不行你就說你以前寫過下載文件時,用過多線程技術,
或者業餘時間用過多線程寫爬蟲,提高效率。
進程:一個運行的程序(代碼)就是一個進程,沒有運行的代碼叫程序,進程是系統資源分配的最
小單位,進程擁有本身獨立的內存空間,因此進程間數據不共享,開銷大。
線程: 調度執行的最小單位,也叫執行路徑,不能獨立存在,依賴進程存在一個進程至少有一個
線程,叫主線程,而多個線程共享內存(數據共享,共享全局變量),從而極大地提升了程序的運行效率。
協程:是一種用戶態的輕量級線程,協程的調度徹底由用戶控制。協程擁有本身的寄存器上下文和
棧。 協程調度切換時,將寄存器上下文和棧保存到其餘地方,在切回來的時候,恢復先前保存的寄存
器上下文和棧,直接操做棧則基本沒有內核切換的開銷,能夠不加鎖的訪問全局變量,因此上下文的切
換很是快。
協程也只是單CPU,可是能減少切換代價提高性能
線程是非獨立的,同一個進程裏線程是數據共享的,當各個線程訪問數據資源時會出現競爭狀態即:
數據幾乎同步會被多個線程佔用,形成數據混亂 ,即所謂的線程不安全
那麼怎麼解決多線程競爭問題?-- 鎖。
鎖的好處:
確保了某段關鍵代碼(共享數據資源)只能由一個線程從頭至尾完整地執行能解決多線程資源競爭下
的原子操做問題。
鎖的壞處:
阻止了多線程併發執行,包含鎖的某段代碼實際上只能以單線程模式執行,效率就大大地降低了
鎖的致命問題:死鎖:若干子線程在系統資源競爭時,都在等待對方對某部分資源解除佔用狀態,結果是誰也不肯先解鎖,
互相干等着,程序沒法執行下去,這就是死鎖。
GIL 鎖 全局解釋器鎖(只在 cpython 裏纔有)
做用:限制多線程同時執行,保證同一時間只有一個線程執行,因此 cpython 裏的多線程實際上是僞
多線程!
三者的關係:進程裏有線程,線程裏有協程。
多線程的例子
http://www.javashuo.com/article/p-yyssnnvr-dm.html
同步:多個任務之間有前後順序執行,一個執行完下個才能執行。
異步:多個任務之間沒有前後順序,能夠同時執行有時候一個任務可能要在必要的時候獲取另外一個
同時執行的任務的結果,這個就叫回調!
阻塞:若是卡住了調用者,調用者不能繼續往下執行,就是說調用者阻塞了。
非阻塞:若是不會卡住,能夠繼續執行,就是說非阻塞的。
同步異步相對於多任務而言,阻塞非阻塞相對於代碼執行而言。
多進程適合在 CPU 密集型操做(cpu 操做指令比較多,如位數多的浮點運算)。
多線程適合在 IO 密集型操做(讀寫數據操做較多的,好比爬蟲)。
線程是併發,進程是並行;
進程之間相互獨立,是系統分配資源的最小單位,同一個線程中的全部線程共享資源。
並行:同一時刻多個任務同時在運行。
併發:在同一時間間隔內多個任務都在運行,可是並不會在同一時刻同時運行,存在交替執行的情
況。
實現並行的庫有:multiprocessing
實現併發的庫有:threading
程序須要執行較多的讀寫、請求和回覆任務的須要大量的 IO 操做,IO 密集型操做使用併發更好。
CPU 運算量大的程序程序,使用並行會更好。
IO 密集型:系統運做,大部分的情況是 CPU 在等 I/O (硬盤/內存)的讀/寫。
CPU 密集型:大部份時間用來作計算、邏輯判斷等 CPU 動做的程序稱之 CPU 密集型。
UDP 是面向無鏈接的通信協議,UDP 數據包括目的端口號和源端口號信息。
優勢:UDP 速度快、操做簡單、要求系統資源較少,因爲通信不須要鏈接,能夠實現廣播發送
缺點:UDP 傳送數據前並不與對方創建鏈接,對接收到的數據也不發送確認信號,發送端不知道數
據是否會正確接收,也不重複發送,不可靠。
TCP 是面向鏈接的通信協議,經過三次握手創建鏈接,通信完成時四次揮手
優勢:TCP 在數據傳遞時,有確認、窗口、重傳、阻塞等控制機制,能保證數據正確性,較爲可靠。
缺點:TCP 相對於 UDP 速度慢一點,要求系統資源較多。
先要解析出 baidu.com 對應的 ip 地址
要先使用 arp 獲取默認網關的 mac 地址
組織數據發送給默認網關(ip 仍是 dns 服務器的 ip,可是 mac 地址是默認網關的 mac 地址)
默認網關擁有轉發數據的能力,把數據轉發給路由器
路由器根據本身的路由協議,來選擇一個合適的較快的路徑轉發數據給目的網關
目的網關(dns 服務器所在的網關),把數據轉發給 dns 服務器
dns 服務器查詢解析出 baidu.com 對應的 ip 地址,並原路返回請求這個域名的 client
獲得了 baidu.com 對應的 ip 地址以後,會發送 tcp 的 3 次握手,進行鏈接
使用 http 協議發送請求數據給 web 服務器
web 服務器收到數據請求以後,經過查詢本身的服務器獲得相應的結果,原路返回給瀏覽器。
瀏覽器接收到數據以後經過瀏覽器本身的渲染功能來顯示這個網頁。
瀏覽器關閉 tcp 鏈接,即 4 次揮手結束,完成整個訪問過程
POST 請求的過程:
1.瀏覽器請求 tcp 鏈接(第一次握手)
2.服務器答應進行 tcp 鏈接(第二次握手)
3.瀏覽器確認,併發送 post 請求頭(第三次握手,這個報文比較小,因此 http 會在此時進行
第一次數據發送)
4.服務器返回 100 continue 響應
5.瀏覽器開始發送數據
6.服務器返回 200 ok 響應
GET 請求的過程:
1.瀏覽器請求 tcp 鏈接(第一次握手)
2.服務器答應進行 tcp 鏈接(第二次握手)
3.瀏覽器確認,併發送 get 請求頭和數據(第三次握手,這個報文比較小,因此 http 會在此時
進行第一次數據發送)
4.服務器返回 200 OK 響應
100-199:表示服務器成功接收部分請求,要求客戶端繼續提交其他請求才能完成整個處理過程。
200-299:表示服務器成功接收請求並已完成處理過程,經常使用 200(OK 請求成功)。
300-399:爲完成請求,客戶須要進一步細化請求。302(全部請求頁面已經臨時轉移到新的 url)。
30四、307(使用緩存資源)。
400-499:客戶端請求有錯誤,經常使用 404(服務器沒法找到被請求頁面),403(服務器拒絕訪問,
權限不夠)。
500-599:服務器端出現錯誤,經常使用 500(請求未完成,服務器遇到不可預知的狀況)。
三次握手過程:
1 首先客戶端向服務端發送一個帶有 SYN 標誌,以及隨機生成的序號 100(0 字節)的報文
2 服務端收到報文後返回一個報文(SYN200(0 字節),ACk1001(字節+1))給客戶端
3 客戶端再次發送帶有 ACk 標誌 201(字節+)序號的報文給服務端
至此三次握手過程結束,客戶端開始向服務端發送數據。
1 客戶端向服務端發起請求:我想給你通訊,你準備好了麼?
2 服務端收到請求後迴應客戶端:I'ok,你準備好了麼
3 客戶端禮貌的再次回一下客戶端:準備就緒,我們開始通訊吧!
整個過程跟打電話的過程如出一轍:1 喂,你在嗎 2 在,我說的你聽獲得不 3 恩,聽獲得(接下來請
開始你的表演)
補充:SYN:請求詢問,ACk:回覆,迴應。
四次揮手過程:
因爲 TCP 鏈接是能夠雙向通訊的(全雙工),所以每一個方向都必須單獨進行關閉(這句話纔是
精闢,後面四個揮手過程都是其具體實現的語言描述)
四次揮手過程,客戶端和服務端均可以先開始斷開鏈接
1 客戶端發送帶有 fin 標識的報文給服務端,請求通訊關閉
2 服務端收到信息後,回覆 ACK 答應關閉客戶端通訊(鏈接)請求
3 服務端發送帶有 fin 標識的報文給客戶端,也請求關閉通訊
4 客戶端迴應 ack 給服務端,答應關閉服務端的通訊(鏈接)請求
1. Host (主機和端口號)
2. Connection (連接類型)
3. Upgrade-Insecure-Requests (升級爲 HTTPS 請求)
4. User-Agent (瀏覽器名稱)
5. Accept (傳輸文件類型)
6. Referer (頁面跳轉處)
7. Accept-Encoding(文件編解碼格式)
8. Cookie (Cookie)
9. x-requested-with :XMLHttpRequest (是 Ajax 異步請求)
IP: 網絡層
TCP/UDP: 傳輸層
HTTP、RTSP、FTP: 應用層協議
scheme://host[:port#]/path/…/[?query-string][#anchor]
協議://IP地址:端口號/資源路徑/參數 錨
ajax(異步的 javascript 和 xml) 可以刷新局部網頁數據而不是從新加載整個網頁。
第一步,建立 xmlhttprequest 對象,var xmlhttp =new XMLHttpRequest();XMLHttpRequest
對象用來和服務器交換數據。
第二步,使用 xmlhttprequest 對象的 open()和 send()方法發送資源請求給服務器。
第三步,使用 xmlhttprequest 對象的 responseText 或 responseXML 屬性得到服務器的響應。
第四步,onreadystatechange 函數,當發送請求到服務器,咱們想要服務器響應執行一些功能就
須要使用 onreadystatechange 函數,每次 xmlhttprequest 對象的 readyState 發生改變都會觸發
onreadystatechange 函數。
pyc文件就是py程序編譯後獲得的文件,是一種二進制文件。看成爲模板被調用的時候會自動生成pyc文件,固然也能夠經過代碼去生成。
做用:
一、提升運行效率:python是解釋性語言,須要經過python解釋器編譯,先編譯出pyc文件能夠下降編譯時間提升運行效率。
二、不想讓源碼泄露:pyc文件能夠獨立於py文件,刪除py文件也不會出錯,第二次運行會優先尋找pyc文件。並且pyc文件沒法進行反編譯,因此,爲了防止源碼泄露能夠直接發佈pyc文件。
在 django 中,路由是瀏覽器訪問服務器時,先訪問的項目中的 url,再由項目中的 url 找到應用中
url,這些 url 是放在一個列表裏,聽從從前日後匹配的規則。在 flask 中,路由是經過裝飾器給每一個視
圖函數提供的,並且根據請求方式的不一樣能夠一個 url 用於不一樣的做用。
django-admin startproject 項目名稱
python manage.py startapp 應用 app 名
M:Model,模型,和 MVC 中的 M 功能相同,和數據庫進行交互。
V:view,視圖,和 MVC 中的 C 功能相同,接收請求,進行處理,與 M 和 T 進行交互,返回應答。
T:Template,模板,和 MVC 中的 V 功能相同,產生 Html 頁面
一、 用戶點擊註冊按鈕,將要註冊的內容發送給網站的服務器。
二、 View 視圖,接收到用戶發來的註冊數據,View 告訴 Model 將用戶的註冊信息保存進數據庫。
三、 Model 層將用戶的註冊信息保存到數據庫中。
四、 數據庫將保存的結果返回給 Model
五、 Model 將保存的結果給 View 視圖。
六、 View 視圖告訴 Template 模板去產生一個 Html 頁面。
七、 Template 生成 html 內容返回給 View 視圖。
八、 View 將 html 頁面內容返回給瀏覽器。
九、 瀏覽器拿到 view 返回的 html 頁面內容進行解析,展現。
將驗證碼保存到數據庫或 session,設置過時時間爲 1 分鐘,而後頁面設置一個倒計時(通常是前端
js 實現 這個計時)的展現,一分鐘事後再次點擊獲取新的信息。
django:主要是用來搞快速開發的,他的亮點就是快速開發,節約成本,正常的併發量不過 10000,
若是要實現高併發的話,就要對 django 進行二次開發,好比把整個笨重的框架給拆掉,本身寫 socket
實現 http 的通訊,底層用純 c,c++寫提高效率,ORM 框架給幹掉,本身編寫封裝與數據庫交互的框
架,由於啥呢,ORM 雖然面向對象來操做數據庫,可是它的效率很低,使用外鍵來聯繫表與表之間的
查詢;
flask:輕量級,主要是用來寫接口的一個框架,實現先後端分離,提高開發效率,Flask 自己至關於一
個內核,其餘幾乎全部的功能都要用到擴展(郵件擴展 Flask-Mail,用戶認證 Flask-Login),都須要
用第三方的擴展來實現。好比能夠用 Flask-extension 加入 ORM、窗體驗證工具,文件上傳、身份驗
證等。Flask 沒有默認使用的數據庫,你能夠選擇 MySQL,也能夠用 NoSQL。
Tornado: Tornado 是一種 Web 服務器軟件的開源版本。Tornado 和如今的主流 Web 服務器框
架(包括大多數 Python 的框架)有着明顯的區別:它是非阻塞式服務器,並且速度至關快。
得利於其非阻塞的方式和對 epoll 的運用,Tornado 每秒能夠處理數以千計的鏈接,所以 Tornado
是實時 Web 服務的一個 理想框架。
你吃飯吃到一半,電話來了,你一直到吃完了之後纔去接,這就說明你不支持併發也不支持並行。
你吃飯吃到一半,電話來了,你停了下來接了電話,接完後繼續吃飯,這說明你支持併發。 (不必定是同時的)
你吃飯吃到一半,電話來了,你一邊打電話一邊吃飯,這說明你支持並行。
併發的關鍵是你有處理多個任務的能力,不必定要同時。
並行的關鍵是你有同時處理多個任務的能力。
因此我認爲它們最關鍵的點就是:是不是『同時』。
併發是輪流處理多個任務,並行是同時處理多個任務
-------------------------------------------------------------------------
若是某個系統支持兩個或者多個動做(Action)同時存在,那麼這個系統就是一個併發系統。若是某個系統支持兩個或者多個動做同時執行,那麼這個系統就是一個並行系統。併發系統與並行系統這兩個定義之間的關鍵差別在於「存在」這個詞。
在併發程序中能夠同時擁有兩個或者多個線程。這意味着,若是程序在單核處理器上運行,那麼這兩個線程將交替地換入或者換出內存。這些線程是同時「存在」的——每一個線程都處於執行過程當中的某個狀態。若是程序可以並行執行,那麼就必定是運行在多核處理器上。此時,程序中的每一個線程都將分配到一個獨立的處理器核上,所以能夠同時運行。
我相信你已經可以得出結論——「並行」概念是「併發」概念的一個子集。也就是說,你能夠編寫一個擁有多個線程或者進程的併發程序,但若是沒有多核處理器來執行這個程序,那麼就不能以並行方式來運行代碼。所以,凡是在求解單個問題時涉及多個執行流程的編程模式或者執行行爲,都屬於併發編程的範疇。
摘自:《併發的藝術》 — 〔美〕佈雷謝斯
同步異步指的是在客戶端
同步意味着客戶端提出了一個請求之後,在迴應以前只能等待
異步意味着 客戶端提出一個請求之後,還能夠繼續提其餘請求阻塞
非阻塞 指的是服務器端
阻塞意味着服務器接受一個請求後,在返回結果之前不能接受其餘請求
非阻塞意味着服務器接受一個請求後,儘管沒有返回結果,仍是能夠繼續接受其餘請求
第一範式:確保每列的原子性. 若是每列(或者每一個屬性)都是不可再分的最小數據單元(也稱爲最小的原子單元),則知足第一範式.
例如:顧客表(姓名、編號、地址、……)其中"地址"列還能夠細分爲國家、省、市、區等。
第二範式:在第一範式的基礎上更進一層,目標是確保表中的每列都和主鍵相關. 若是一個關係知足第一範式,而且除了主鍵之外的其它列,都依賴於該主鍵,則知足第二範式.
例如:訂單表(訂單編號、產品編號、定購日期、價格、……),"訂單編號"爲主鍵,"產品編號"和主鍵列沒有直接的關係,即"產品編號"列不依賴於主鍵列,應刪除該列。
第三範式:在第二範式的基礎上更進一層,目標是確保每列都和主鍵列直接相關,而不是間接相關. 若是一個關係知足第二範式,而且除了主鍵之外的其它列都不依賴於主鍵列,則知足第三範式. 爲了理解第三範式,須要根據Armstrong千米之必定義傳遞依賴。
假設A、B和C是關係R的三個屬性,若是A-〉B且B-〉C,則從這些函數依賴中,能夠得出A-〉C,如上所述,依賴A-〉C是傳遞依賴。
例如:訂單表(訂單編號,定購日期,顧客編號,顧客姓名,……),初看該表沒有問題,知足第二範式,每列都和主鍵列"訂單編號"相關,再細看你會發現"顧客姓名"和"顧客編號"相關,"顧客編號"和"訂單編號"又相關,最後通過傳遞依賴,"顧客姓名"也和"訂單編號"相關。爲了知足第三範式,應去掉"顧客姓名"列,放入客戶表中。