主頁 > 後端開發 > 超實用的Flask入門基礎教程,新手必備!

超實用的Flask入門基礎教程,新手必備!

2020-10-10 05:30:30 後端開發

Flask入門基礎教程

Flask簡介

Flask是一個輕量級的可定制框架,使用Python語言撰寫,較其他同型別框架更為靈活、輕便、安全且容易上手,它可以很好地結合MVC模式進行開發,開發人員分工合作,小型團隊在短時間內就可以完成功能豐富的中小型網站或Web服務的實作,另外,Flask還有很強的定制性,用戶可以根據自己的需求來添加相應的功能,在保持核心功能簡單的同時實作功能的豐富與擴展,其強大的插件庫可以讓用戶實作個性化的網站定制,開發出功能強大的網站,

 

安裝Flask

依賴

當安裝 Flask 時,以下配套軟體會被自動安裝:

> - Werkzeug 用于實作 WSGI 是一個 WSGI(在 Web 應用和多種服務器之間的標準 Python 介面) 工具集,

> - jinja2是Python的一個流行的模板引擎,Web模板系統將模板與特定資料源組合以呈現動態網頁,

> - MarkupSafe 與 Jinja 共用,在渲染頁面時用于避免不可信的輸入,防止注入攻擊,

> - ItsDangerous 保證資料完整性的安全標志資料,用于保護 Flask 的 session cookie.

> - Click 是一個命令列應用的框架,用于提供 flask 命令,并允許添加自定義 管理命令,

 

創建虛擬環境

創建檔案夾,在檔案夾下面 輸入命令

python -m venv venv_name

激活虛擬環境

激活這個虛擬環境(注意,使用的是虛擬環境的話前面會有(venv_name)這個顯示的,不然就是沒有激活虛擬環境,)

venv_name\Scripts\activate

 

安裝Flask

在已激活的虛擬環境中使用pip安裝Flask

pip install Flask

 

基礎介紹

在Flask中,最基礎的一個功能是這樣子的

from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
return 'Hello, World!'

if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0', port=5000)

 

  1.  首先,我們導入了Flask類,
  2. 其次我們創建了Flask的實體,第一個引數是應用模塊或者包的名稱, 如果你使用單一的模塊(如本例),你應該使用 __name__ ,因為模塊的名稱將會因其作為單獨應用啟動還是作為模塊匯入而有不同( 也即是 '__main__' 或實際的匯入名),這是必須的,這樣 Flask 才知道到哪去找模板、靜態檔案等等,
  3. route()是一個路由,其實是一個裝飾器,在其中輸入URL,會幫我們在這個URL下執行對應的方法,
  4. 接著是函式主體,可以寫方法也可以呼叫其他方法的回傳值,最后回傳到瀏覽器上顯示的資訊
  5. 最后我們用 run() 函式來讓應用運行在本地服務器上, 其中 if __name__ =='__main__': 確保服務器只會在該腳本被 Python 解釋器直接執行的時候才會運行,而不是作為模塊匯入的時候,debug=True開啟了除錯模式,相當于在發生錯誤時提供一個相當有用的除錯器,host=’0.0.0.0‘可以允許同一個局域網內別的用戶訪問,這個方法讓作業系統監聽所有公網 IP,port自定義埠,

 

路由

現代Web框架使用路由技術來幫助用戶記住應用程式URL,可以直接訪問所需的頁面,而無需從主頁導航,Flask中的route()裝飾器用于將URL系結到函式,例如:

@app.route('/index')
def index():
return 'This is a index page...'

 

在這里,URL '/ index' 規則系結到index()函式, 因此,如果用戶訪問127.0.0.1:5000/index,index()函式的輸出將在瀏覽器中呈現,


變數規則

通過把 URL 的一部分標記為 <variable_name> 就可以在 URL 中添加變數,標記的 部分會作為關鍵字引數傳遞給函式,通過使用 <converter:variable_name> ,可以 選擇性的加上一個轉換器,為變數指定規則,請看下面的例子:

 

@app.route('/user/<username>')
def show_user_profile(username):
# show the user profile for that user
return 'User %s' % escape(username)

@app.route('/post/<int:post_id>')
def show_post(post_id):
# show the post with the given id, the id is an integer
return 'Post %d' % post_id

@app.route('/path/<path:subpath>')
def show_subpath(subpath):
# show the subpath after /path/
return 'Subpath %s' % escape(subpath)

 

轉換器型別:

型別 說明 
string  (預設值) 接受任何不包含斜杠的文本
int  接受正整數
float  接受正浮點數
path 類似string,但可以包含斜杠
uuid  接受UUID字串

 


唯一 URL / 重定向行為

Flask的URL規則是基于Werkzeug的路由模塊,模塊背后的思想是基于 Apache 以及更早的 HTTP 服務器主張的先例,保證優雅且唯一的 URL,

 

@app.route('/projects/')
def projects():
return 'The project page'

@app.route('/about')
def about():
return 'The about page'

 

訪問第一個路由不帶/時,Flask會自動重定向到正確地址,
訪問第二個路由時末尾帶上/后Flask會直接報404 NOT FOUND錯誤,

永久性重定向和暫時性重定向
flask是通過flask.redirect(location,code=302)這個函式來實作重定向的,location是需要重定向到的url,應該配合之前講的在url_for()函式來使用,code表示哪種重定向,默認302,也即暫時性重定向,301是永久性重定向.

 

構建URL

如果 Flask 能匹配 URL,那么 Flask 可以生成它們嗎?當然可以,你可以用 url_for()來給指定的函式構造 URL,它接受函式名作為第一個引數,也接受對應 URL 規則的變數部分的命名引數,未知變數部分會添加到 URL 末尾作為查詢引數,
例如,這里我們使用 test_request_context() 方法來嘗試使用 url_for() , test_request_context() 告訴 Flask 正在處理一個請求,而實際上也許我們正處在互動 Python shell 之中, 并沒有真正的請求,

from flask import Flask, url_for

app = Flask(__name__)

@app.route('/')
def index(): 
return 'index'

@app.route('/login')
def login(): 
return 'login'

@app.route('/user/<username>')
def profile(username):
return '{}\'s profile'.format(escape(username))

with app.test_request_context():
print(url_for('index'))    #輸出 /
print(url_for('login'))    #輸出 /login
print(url_for('login', next='/'))    #輸出 /login?next=/
print(url_for('profile', username='John Doe'))    #輸出 /user/John%20Doe

 

那么為什么不在把 URL 寫死在模板中,而要使用反轉函式 url_for() 動態構建?

  1. 反轉通常比硬編碼 URL 的描述性更好,
  2. 你可以只在一個地方改變 URL ,而不用到處亂找,
  3. URL 創建會為你處理特殊字符的轉義和 Unicode 資料,比較直觀,
  4. 生產的路徑總是絕對路徑,可以避免相對路徑產生副作用,
  5. 如果你的應用是放在 URL 根路徑之外的地方(如在 /myapplication 中,不在 / 中), url_for() 會為你妥善處理,

 

HTTP方法

Web 應用使用不同的 HTTP 方法處理 URL ,當你使用 Flask 時,應當熟悉 HTTP 方法, 預設情況下,一個路由只回應 GET 請求, 可以使用 route() 裝飾器的 methods 引數來處理不同的 HTTP 方法:

from flask import request

@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
return do_the_login()
else:
return show_the_login_form()如果當前使用了 GET 方法, Flask 會自動添加 HEAD 方法支持,并且同時還會 按照 HTTP RFC 來處理 HEAD 請求,同樣, OPTIONS 也會自動實作,

HTTP 方法(也經常被叫做“謂詞”)告知服務器,客戶端想對請求的頁面 做 些什么,下面的都是非常常見的方法:

  1. GET:瀏覽器告知服務器:只 獲取 頁面上的資訊并發給我,這是最常用的方法,
  2. HEAD:瀏覽器告訴服務器:欲獲取資訊,但是只關心 訊息頭,應用應像處理 GET 請求一樣來處理它,但是不分發實際內容,在 Flask 中你完全無需 人工 干預,底層的 Werkzeug 庫已經替你打點好了,
  3. POST:瀏覽器告訴服務器:想在 URL 上 發布 新資訊,并且,服務器必須確保 資料已存盤且僅存盤一次,這是HTML 表單通常發送資料到服務器的方法,
  4. PUT:類似 POST 但是服務器可能觸發了存盤程序多次,多次覆寫掉舊值,你可能會問這有什么用,當然這是有原因的,考慮到傳輸中連接可能會丟失,在 這種
  5.  情況下瀏覽器和服務器之間的系統可能安全地第二次接收請求,而不破壞其它東西,因為 POST它只觸發一次,所以用 POST是不可能的,
  6. DELETE:洗掉給定位置的資訊,
  7. OPTIONS:給客戶端提供一個敏捷的途徑來弄清這個 URL 支持哪些 HTTP 方法,從 Flask 0.6 開始,實作了自動處理,

 

Request物件

from flask import Flask,jsonify
from flask import request

@app.route('/api/add', methods=['POST'])
def add_elasticsearch():
city_name = request.form.get('city_name')
diagnose_people = request.form.get('diagnose_people')
suspect_people = request.form.get('suspect_people')
death_people = request.form.get('death_people')
cure_people = request.form.get('cure_people')
result = main.FuncUtil.add_es(city_name, diagnose_people, suspect_people, death_people, cure_people)
return jsonify(result)

request中”method”變數可以獲取當前請求的方法,即”GET”, “POST”, “DELETE”, “PUT”等,”form”變數是一個字典,可以獲取Post請求表單中的內容,如果提交的表單中不存在,則會回傳一個”KeyError”,你可以不捕獲,頁面會回傳400錯誤(想避免拋出這”KeyError”,你可以用request.form.get(“user”)來替代),而”request.args.get()”方法則可以獲取Get請求URL中的引數,該函式的第二個引數是默認值,當URL引數不存在時,則回傳默認值,在后文的請求物件會講到,

 

 靜態檔案

動態 web 應用也會需要靜態檔案,通常是 CSS 和 JavaScript 檔案,理想狀況下, 你已經配置好 Web 服務器來提供靜態檔案,但是在開發中,Flask 也可以做到, 只要在你的包中或是模塊的所在目錄中創建一個名為 static 的檔案夾,在應用中使用 /static 即可訪問,
給靜態檔案生成 URL ,使用特殊的 'static' 端點名:

url_for('static', filename='style.css')

這個檔案應該存盤在檔案系統上的 static/style.css ,


模板渲染

Flask的模板功能是基于Jinja2模板引擎實作的,讓我們來實作一個例子,修改之前的Flask運行檔案,代碼如下:

from flask import Flask,render_template

app = Flask(__name__)

@app.route('/hello/<name>')
def hello_world(name=None):
return render_template('hello.html', name=name)

if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0', port=5000)

 


這段代碼”hello()”函式并不是直接回傳字串,而是呼叫了”render_template()”方法來渲染模板,方法的第一個引數”hello.html”指向你想渲染的模板名稱,第二個引數”name”是你要傳到模板去的變數,變數可以傳多個,接下來我們創建模板檔案,在當前目錄下,創建一個子目錄”templates”(注意,一定要使用這個名字),然后在”templates”目錄下創建檔案”hello.html”,內容如下:

<!doctype html>
<title>Hello Reader</title>

{% if name %}
<h1>Hello {{ name }}!</h1>

{% else %}
<h1>Hello World!</h1>

{% endif %}

這是一個HTML模板,根據”name”變數的值,顯示不同的內容,變數或運算式由”{{ }}”修飾,而控制陳述句由”{% %}”修飾,其他的代碼,就是我們常見的HTML,打開瀏覽器,輸入”http://127.0.0.1:5000/hello/Reader”,頁面上即顯示大標題”Hello Reader !”,

 

模板繼承

一般我們的網站雖然頁面多,但是很多部分是重用的,比如頁首,頁腳,導航欄之類的,對于每個頁面,都要寫這些代碼,很麻煩,Flask的Jinja2模板支持模板繼承功能,省去了這些重復代碼,讓我們基于上面的例子,在”templates”目錄下,創建一個名為”layout.html”的模板:

<!doctype html>

<title>Hello xxx</title>

<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='style.css') }}">

<div class="page">

{% block body %}

{% endblock %}

</div>

再修改之前的”hello.html”,把原來的代碼定義在”block body”中,并在代碼一開始”繼承”上面的”layout.html”:

{% extends "layout.html" %}
{% block body %}

{% if name %}
<h1>Hello {{ name }}!</h1>

{% else %}
<h1>Hello World!</h1>

{% endif %}
{% endblock %}

 


打開瀏覽器,再看下”http://127.0.0.1:5000/hello/Reader”頁面的原始碼,

<!doctype html>
<title>Hello xxx</title>

<link rel="stylesheet" type="text/css" href="/static/style.css">

<div class="page">

<h1>Hello Reader!</h1>
</div>

 


你會發現,雖然”render_template()”加載了”hello.html”模板,但是”layout.html”的內容也一起被加載了,而且”hello.html”中的內容被放置在”layout.html”中”{% block body %}”的位置上,形象的說,就是”hello.html”繼承了”layout.html”,

 

訪問請求資料

對于 Web 應用,與客戶端發送給服務器的資料互動至關重要,在 Flask 中由全域的 request 物件來提供這些資訊,如果你有一定的 Python 經驗,你會好奇,為什么這個物件是全域的,為什么 Flask 還能保證執行緒安全,答案是本地環境,


本地環境

Flask 中的某些物件是全域物件,但卻不是通常的那種,這些物件實際上是特定環境的區域物件的代理,雖然很拗口,但實際上很容易理解,

想象一下處理執行緒的環境,一個請求傳入,Web 服務器決定生成一個新執行緒( 或者別的什么東西,只要這個底層的物件可以勝任并發系統,而不僅僅是執行緒), 當 Flask 開始它內部的請求處理時,它認定當前執行緒是活動的環境,并系結當前的應用和 WSGI 環境到那個環境上(執行緒),它的實作很巧妙,能保證一個應用呼叫另一個應用時不會出現問題,

所以,這對你來說意味著什么?除非你要做類似單元測驗的東西,否則你基本上可以完全無視它,你會發現依賴于一段請求物件的代碼,因沒有請求物件無法正常運行,解決方案是,自行創建一個請求物件并且把它系結到環境中,單元測驗的最簡單的解決方案是:用 test_request_context() 環境管理器,結合 with 宣告,系結一個測驗請求,這樣你才能與之互動,下面是一個例子:

from flask import request

with app.test_request_context('/hello', method='POST'):
# 現在,你可以對請求執行某些操作,直到with塊結束為止,例如基本斷言:
assert request.path == '/hello'
assert request.method == 'POST'

 


另一種可能是:傳遞整個 WSGI 環境給 request_context() 方法:

from flask import request

with app.request_context(environ):
assert request.method == 'POST'

 

 


請求物件

通過使用 method 屬性可以操作當前請求方法,通過使用 form 屬性處理表單資料(在 POST 或者 PUT 請求 中傳輸的資料),以下是使用上述兩個屬性的例子:

from flask import render_template

@app.route('/login', methods=['POST', 'GET'])
def login():
error = None
if request.method == 'POST':
if valid_login(request.form['username'],
request.form['password']):
return log_the_user_in(request.form['username'])
else:
error = 'Invalid username/password'
#如果請求方法為GET或憑據無效,則執行以下代碼
return render_template('login.html', error=error)

 

當 form 屬性中不存在這個鍵時會發生什么?會引發一個 KeyError , 如果你不像捕捉一個標準錯誤一樣捕捉 KeyError ,那么會顯示一個 HTTP 400 Bad Request 錯誤頁面,因此,多數情況下你不必處理這個問題,
要操作 URL (如 ?key=value )中提交的引數可以使用 args 屬性:
searchword = request.args.get('key', '')
用戶可能會改變 URL 導致出現一個 400 請求出錯頁面,這樣降低了用戶友好度,因此, 我們推薦使用 get 或通過捕捉 KeyError 來訪問 URL 引數,


檔案上傳

用 Flask 處理檔案上傳很容易,只要確保不要忘記在你的 HTML 表單中設定 enctype="multipart/form-data" 屬性就可以了,否則瀏覽器將不會傳送你的檔案,
已上傳的檔案被儲存在記憶體或檔案系統的臨時位置,你可以通過請求物件 files 屬性來訪問上傳的檔案,每個上傳的檔案都儲存在這個 字典型屬性中,這個屬性基本和標準 Python file 物件一樣,另外多出一個 用于把上傳檔案保存到服務器的檔案系統中的 save() 方法,下例展示其如何運作:

from flask import request

@app.route('/upload', methods=['GET', 'POST'])
def upload_file():
if request.method == 'POST':
f = request.files['the_file']
f.save('/var/www/uploads/uploaded_file.txt')

 

如果想要知道檔案上傳之前其在客戶端系統中的名稱,可以使用 filename 屬性,但是請牢記這個值是 可以偽造的,永遠不要信任這個值,如果想要把客戶端的檔案名作為服務器上的檔案名, 可以通過 Werkzeug 提供的 secure_filename() 函式:

from flask import request
from werkzeug.utils import secure_filename

@app.route('/upload', methods=['GET', 'POST'])
def upload_file():
if request.method == 'POST':
f = request.files['the_file']
f.save('/var/www/uploads/' + secure_filename(f.filename))

 

 

Cookies

要訪問 cookies ,可以使用 cookies 屬性,可以使用回應 物件 的 set_cookie 方法來設定 cookies ,請求物件的 cookies 屬性是一個包含了客戶端傳輸的所有 cookies 的字典,在 Flask 中,如果使用 會話 ,那么就不要直接使用 cookies ,因為 會話 比較安全一些,
讀取 cookies:

from flask import request

@app.route('/')
def index():
username = request.cookies.get('username')
# use cookies.get(key) instead of cookies[key] to not get a
# KeyError if the cookie is missing.

 

儲存 cookies:

from flask import make_response

@app.route('/')
def index():
resp = make_response(render_template(...))
resp.set_cookie('username', 'the username')
return resp

 

注意, cookies 設定在回應物件上,通常只是從視圖函式回傳字串, Flask 會把它們 轉換為回應物件,如果你想顯式地轉換,那么可以使用 make_response() 函式,然后再修改它,
使用 延遲的請求回呼 方案可以在沒有回應物件的情況下設定一個 cookie ,

 

重定向和錯誤

你可以用 redirect() 函式把用戶重定向到其它地方,放棄請求并回傳錯誤代碼,用 abort() 函式,這里是一個它們如何使用的例子:

from flask import abort, redirect, url_for

@app.route('/')
def index():
return redirect(url_for('login'))

@app.route('/login')
def login():
abort(401)
this_is_never_executed()

 

這是一個相當無意義的例子因為用戶會從主頁重定向到一個不能訪問的頁面 (401 意味著禁止訪問),但是它展示了重定向是如何作業的,

默認情況下,錯誤代碼會顯示一個黑白的錯誤頁面,如果你要定制錯誤頁面, 可以使用 errorhandler() 裝飾器:

from flask import render_template

@app.errorhandler(404)
def page_not_found(error):
return render_template('page_not_found.html'), 404

 

注意 render_template() 呼叫之后的 404 ,這告訴 Flask,該頁的錯誤代碼是 404 ,即沒有找到,默認為 200,也就是一切正常,

 

回應

視圖函式的回傳值會被自動轉換為一個回應物件,如果回傳值是一個字串, 它被轉換為該字串為主體的、狀態碼為 200 OK的 、 MIME 型別是text/html 的回應物件,Flask 把回傳值轉換為回應物件的邏輯是這樣:
> 1. 如果回傳的是一個合法的回應物件,它會從視圖直接回傳,
> 2. 如果回傳的是一個字串,回應物件會用字串資料和默認引數創建,
> 3. 如果回傳的是一個字典,那么呼叫 jsonify 創建一個回應物件,
> 4. 如果回傳的是一個元組,且元組中的元素可以提供額外的資訊,這樣的元組必須是(response, status, headers) 的形式,且至少包含一個元素, status 值會覆寫狀態代碼, headers可以是一個串列或字典,作為額外的訊息標頭值,
> 5. 如果上述條件均不滿足, Flask 會假設回傳值是一個合法的 WSGI應用程式,并轉換為一個請求物件, 如果你想在視圖里操縱上述步驟結果的回應物件,可以使用 make_response() 函式,

譬如你有這樣一個視圖:

@app.errorhandler(404)
def not_found(error):
return render_template('error.html'), 404

 


你只需要把回傳值運算式傳遞給 make_response() ,獲取結果物件并修改,然后再回傳它:

@app.errorhandler(404)
def not_found(error):
resp = make_response(render_template('error.html'), 404)
resp.headers['X-Something'] = 'A value'
return resp

 

 


 JSON 格式的 API

JSON 格式的回應是常見的,用 Flask 寫這樣的 API 是很容易上手的,如果從視圖 回傳一個 dict ,那么它會被轉換為一個 JSON 回應,

@app.route("/me")
def me_api():
user = get_current_user()
return {
"username": user.username,
"theme": user.theme,
"image": url_for("user_image", filename=user.image),
}

 

如果 dict 還不能滿足需求,還需要創建其他型別的 JSON 格式回應,可以使用 jsonify() 函式,該函式會序列化任何支持的 JSON 資料型別, 也可以研究研究 Flask 社區擴展,以支持更復雜的應用,

@app.route("/users")
def users_api():
users = get_all_users()
return jsonify([user.to_json() for user in users])

 

 

會話

除了請求物件之外還有一種稱為 session 的物件,允許你在不同請求 之間儲存資訊,這個物件相當于用密鑰簽名加密的 cookie ,即用戶可以查看你的 cookie ,但是如果沒有密鑰就無法修改它,
使用會話之前你必須設定一個密鑰,舉例說明:

from flask import Flask, session, redirect, url_for, escape, request

app = Flask(__name__)

#設定一個隨機密鑰
app.secret_key = b'_5#y2L"F4Q8z\n\xec]/'

@app.route('/')
def index():
if 'username' in session:
return 'Logged in as %s' % escape(session['username'])
return 'You are not logged in'

@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
session['username'] = request.form['username']
return redirect(url_for('index'))
return '''
<form method="post">
<p><input type=text name=username>
<p><input type=submit value=https://www.cnblogs.com/Zhengnengjin/p/Login>

'''

@app.route('/logout')
def logout():
# remove the username from the session if it's there
session.pop('username', None)
return redirect(url_for('index'))

 

這里用到的 escape() 是用來轉義的,如果不使用模板引擎就可以像上例 一樣使用這個函式來轉義,

如何生成一個好的密鑰
生成亂數的關鍵在于一個好的隨機種子,因此一個好的密鑰應當有足夠的隨機性, 作業系統可以有多種方式基于密碼隨機生成器來生成隨機資料,使用下面的命令 可以快捷的為 Flask.secret_key ( 或者 SECRET_KEY )生成值:

import os 
print(os.urandom(16))    #b'_5#y2L"F4Q8z\n\xec]/'

 


基于 cookie 的會話的說明: Flask 會取出會話物件中的值,把值序列化后儲存到 cookie 中,在打開 cookie 的情況下,如果需要查找某個值,但是這個值在請求中 沒有持續儲存的話,那么不會得到一個清晰的出錯資訊,請檢查頁面回應中的 cookie 的大小是否與網路瀏覽器所支持的大小一致,
除了預設的客戶端會話之外,還有許多 Flask 擴展支持服務端會話,

訊息閃現

一個好的應用和用戶介面都有良好的反饋,否則到后來用戶就會討厭這個應用, Flask 通過閃現系統來提供了一個易用的反饋方式,閃現系統的基本作業原理是在請求結束時 記錄一個訊息,提供且只提供給下一個請求使用,通常通過一個布局模板來展現閃現的 訊息,
flash() 用于閃現一個訊息,在模板中,使用 get_flashed_messages() 來操作訊息


日志

有時候可能會遇到資料出錯需要糾正的情況,例如因為用戶篡改了資料或客戶端代碼出錯 而導致一個客戶端代碼向服務器發送了明顯錯誤的 HTTP 請求,多數時候在類似情況下 回傳 400 Bad Request 就沒事了,但也有不會回傳的時候,而代碼還得繼續運行下去,
這時候就需要使用日志來記錄這些不正常的東西了,自從 Flask 0.3 后就已經為你配置好 了一個日志工具,
以下是一些日志呼叫示例:

app.logger.debug('A value for debugging')
app.logger.warning('A warning occurred (%d apples)', 42)
app.logger.error('An error occurred')

 

 

部署到 Web 服務器

準備好部署你的 Flask 應用了嗎?你可以立即部署到付費的或者免費的服務器來完成快速入門,

 

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/165607.html

標籤:Python

上一篇:【2020Python修煉記22】Python語法入門—運算式與生成式-匿名函式-函式遞回

下一篇:SublimeのJedi (自動補全)

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more